元表
元表 : 类似于操作方式,里面包含了一系列的解决方案,那么这一系列的解决方案就是元方法。
__index
当这个表索引失败的时候处理情况的例如:
father =
{
house=1
}
son =
{
car=1
}
setmetatable(son, father) --把son的metatable设置为father
print(son.house) --nil
此时我们并没有给具体的解决方案
再看
father = {
house=1
}
father.__index = father -- 把father的__index方法指向自己
son = {
car=1
}
son的元表设置为father
setmetatable(son, father)
print(son.house)
结果是符合预期为 -1- 原因是给定了具体的解决方案 :__index
解析:首先在son 中没有找到house,发现son的元表是father于是到father中查找__index方法(注意是查找__index ,并不是father本身),而__index指定的表是father于是就查找father表于是找到了。
- 总结(Lua 查找表元素时的规则)
- 在表中查找,如果找到返回,没有则继续
- 判断该表是否有元表,没有元表,返回nil,否则继续
- 判断元表中(操作指南)是否有没有索引失败的指南(__index) 没有,返回nil,有如果__index是一个表 那么重复1 2 3,如果是一个方法直接返回该函数的值
__call
元方法__call 允许将表当函数使用。
使用方式 __call = function(目标表,参数1,参数2,…)
具体事例:
local test = {}
setmetatable(test, {__call = function(test, a,b )
return a + b
end})
print('=====>>>',test(1,2)) -->> 3
这样我们可以将表当方法使用,另外如果需要将数据记录在该表里面可进行如下操作:
local test = {}
setmetatable(test, {__call = function(test, a,b,fac)
test.a = a
test.b = b
return (a + b) * fac
end})
print('=====>>>',test(1,2,4),test.a,test.b) -->> 12,1,2
另外,可以应用到类里面进行使用
function Class(base, _ctor)
local c = {} -- a new class instance
......
-- expose a constructor which can be called by <classname>(<args>)
local mt = {}
......
mt.__call = function(class_tbl, ...)
local obj = {}
setmetatable(obj,c)
if c._ctor then
c._ctor(obj,...)
end
return obj
end
end
给出一部分,外部使用的时候:
conditionNode = class(baseNode,function(){})
local con = conditionNode() --创建对象