元表 metatable
例如
a=10
b=20
print(a+b)
我们可以得到30,但是如果两个table类型相加呢?
a={"10"}
b={"20"}
print(a+b)
输出结果是:
lua: hello world.lua:3: attempt to perform arithmetic on global 'a' (a table value)
stack traceback:
hello world.lua:3: in main chunk
[C]: ?
>Exit code: 1
因此可以通过定义元表的方式,对于两个table相加的操作进行定义:
a={1,2,3} --定义两个表
b={4,5,6}
mt={} --定义一个元表
mt.__add=function(a,b) --定义加字段的函数功能
local len=table.getn(a) --取a的长度
local res={} --定义一个结果表(用作输出)
for i=1,len do --遍历所有表a中的元素
res[i]=a[i]+b[i] --按照下标访问
end
return res --返回结果表
end
setmetatable(a,mt)
setmetatable(b,mt)
c=a+b
for k,v in ipairs(c) do
print(k,v)
end
输出结果
1 5
2 7
3 9
个人的理解是,这个原表有点像是C++中的运算符重载。其中__add就是用于识别“+”号的运算符。通过mt.__add定义一个function,其中参数就是两个相加的table。而setmetatable就是把两个table类型的a和b关联元表,使其可以使用元表中的方法进行运算。
下面是一个拼接的例子
a={1,2,3}
b={7,8,9}
mt={}
mt.__concat=function(a,b)
local p=table.getn(a)
local q=table.getn(b)
local res={}
for i=1,p do
res[i]=a[i]..b[i]
end
return res
end
setmetatable(a,mt)
setmetatable(b,mt)
c=a..b
for k,v in ipairs(c) do
print(k,v)
end
输出:
1 17
2 28
3 39
每一种运算操作都有对应的字段,最好记住,记不住就查吧
元方法 _ _index
https://blog.csdn.net/u013654125/article/details/100151633
当我们访问一个table中不存在的字段时,会返回什么值呢。一般情况下,会返回一个nil。但是也不一定,Lua按照以下步骤,决定是返回nil还是其他值。
1,当访问一个table字段时,如果有table这个字段,则直接返回对应值。
2,当table没有这个字段时,解释器就回去查找一个叫__index的元方法,接下来会调用对应的元方法,返回元方法返回的值。
3,如果没有这个元方法,则返回nil