chapter 13_0 元方法

  通常,Lua中的每个值都有一套预定义的操作集合。

例如:可以将数字相加、可以连接字符串、可以在table中插入一对key-value等。

但是无法将两个table相加,无法对函数作比较,或无法调用一个字符串。

  可以通过元表来修改一个值的行为,使其在面对一个非预定义的操作时执行一个指定的操作。

例如:假设a和b都是table,通过元表可以定义如何计算表达式a + b。当Lua试图将两个table相加时,它会先检查两者之一是否有元表。

然后检查该元表中是否有一个叫__add的字段。如果Lua找到了该字段,就调用该字段对应的值。这个值也就是所谓的“元方法”

  Lua中的每个值都有一个元表,table和userdata可以有各自独立的元表。而其它类型的值按类型共享元表。

也就是说所有的数字都共享同一个元表,所有的字符串共享一个元表等等。默认情况下,值是没有元表的,但字符串库在

初始化的时候为字符串类型设置了元表。

Lua在创建新的table时不会创建元表:

t = {}
print(getmetatable(t))    --> nil

可以通过setmetatable来设置或修改任何table的元素:

t1 = {}
setmetatable(t,t1)
assert(getmetatable(t) == t1)

在Lua代码中,只能设置table的元表,若要设置其他类型的值的元表,请使用C API

在后面的章节会看到,标准的字符串程序库为所有的字符串都设置了一个元表,其他类型默认是没有元表的。

print(getmetatable("hi"))        -->table :0x80772e0
print(getmetatable("xuxu"))      -->table :0x80772e0
pirnt(getmetatable(10))          -->nil
pirnt(getmetatable(print))       -->nil

任何的table都可以作为其他值的元表,而一组相关的table也可以共享一个通用的元表,此表描述了它们共同的行为。

一个table甚至可以作为自己的元表,用于描述其特有的行为。

以上内容来自:《Lua程序设计第二版》和《Programming in Lua  third edition 

原文地址:https://www.cnblogs.com/daiker/p/5842613.html