本文发布于 1342 天前。
Lua 提供了元表(Metatable),允许我们改变table的行为,每个行为关联了对应的元方法。[1]
定义元表的两个函数
setmetatable(table,metatable)
: 对指定 table 设置元表(metatable),如果元表(metatable)中存在 __metatable
键值,setmetatable 会失败。
getmetatable(table)
: 返回对象的元表(metatable)。
mytable = {} -- 普通表
mymetatable = {} -- 元表
setmetatable(mytable,mymetatable) -- 把 mymetatable 设为 mytable 的元表
也可以写成
mytable = setmetatable({},{})
getmetatable(mytable) -- 这回返回mymetatable
> mymetatable
元方法
__index
当通过键来访问 table 的时候,如果这个键没有值,那么Lua就会寻找该table的metatable(假定有metatable)中的__index 键。[2]
例如
x={23}
xmeta={__index={[2]=45}}
setmetatable(x,xmeta)
print(x[2])
>
45
另一种写法
xmeta={foo=3}
x=setmetatable({},{__index=xmeta})
print(x.foo)
>
3
如果__index
包含一个函数的话,Lua就会调用那个函数,table和键会作为参数传递给函数。
__index
元方法查看表中元素是否存在,如果不存在,返回结果为nil
;如果存在则由__index
返回结果。
设定了元表之后,如果在原来的table中找不到需要的值,则一定会去设定的元表中继续查找。如果已经在原table中找到,那么就不会继续查找。
例如
x={23}
xmeta={__index={[1]=45}}
setmetatable(x,xmeta)
print(x[1])
>
23
__index
还可以被设置为函数。例如,以上的
xmeta={__index={[1]=45}}
等价于
x={23}
xmeta={
__index=function(a,b)
if b == 2 then
return 45
end
end
}
setmetatable(x,xmeta)
print(x[2])