在 Lua table 中我们可以访问对应的 key 来得到 value 值,但是却无法对两个 table 进行操作(比如相加)。
因此 Lua 提供了元表(Metatable),允许我们改变 table 的行为,每个行为关联了对应的元方法。类似于C++中的运算符重载。
一、两个很重要的函数来处理元表:
setmetatable(table,metatable): 对指定 table 设置元表(metatable),如果元表(metatable)中存在 __metatable 键值,setmetatable 会失败。
getmetatable(table): 返回对象的元表(metatable)。
mytable = {} -- 普通表
mymetatable = {} -- 元表
setmetatable(mytable, mymetatable) -- 把 mymetatable 设为 mytable 的元表
-- 也可直接写成如下形式
mytable = setmetatable({}, {})
getmetatable(mytable) -- 这会返回 mymetatable
二、通过添加操作符的方式来定义表之间的运算规则,类似于C++中的运算符重载:
详见官方文档:http://www.lua.org/manual/5.4/manual.html#2.4

使用方法,以__add为例:
T1 = {1, 2, 3, nil, 4}
T2 = {1, 2, 3, 4, 5, 6}
metaT3 = {}
metaT3["__add"] = function(t1, t2)
local len
if #T1 >= #T2 then
len = #T1
else
len = #T2
end
local res = {}
for i = 1, len do
local a = t1[i] or 0
local b = t2[i] or 0
res[i] = a + b
end
return res
end
setmetatable(T1, metaT3)
setmetatable(T2, metaT3)
print("T1 + T2 :")
for k, v in pairs(T1 + T2) do
print(k, v)
end
--执行结果
T1 + T2 :
1 2
2 4
3 6
4 4
5 9
6 6
对于__eq遇到的特殊情况
t1 = {1, 2, 3)
t2 = {1, 2, 3)
metaT3 = {}
metaT3["__eq"] = function(t1,t2)
print("length of t1 = ", #t1)
print("length of t2 = ", #t2)
if #t1 ~= #t2 then
return false
end
for i = 1, #t1 do
if t1[i] ~= t2[i] then
return false
end
end
return true
end
setmetatable(t1, metaT3)
setmetatable(t2, metaT3)
print(t1 == t2)
--执行结果
true
--但是当出现如下情况
t1 = {1, 2, 3}
t2 = {1, 2, 3, nil}
--执行结果
true
--解释:在Lua中table末尾的nil不会被当作有效值进行运算,因此t2末尾有若干个nil,t1 == t2 仍为true.
--但是,非末尾的nil不会被忽视