简介
Lua 提供了元表(Metatable),允许我们改变 table 的行为,每个行为关联了对应的元方法。
- setmetatable(table,metatable): 对指定 table 设置元表(metatable),如果元表(metatable)中存在 __metatable 键值,setmetatable 会失败。
- getmetatable(table): 返回对象的元表(metatable)。
__index
步骤
- 在表中查找,如果找到,返回该元素,找不到则继续
- 判断该表是否有元表,如果没有元表,返回 nil,有元表则继续。
- 判断元表有没有 __index 方法,如果 __index 方法为 nil,则返回 nil;如果 __index 方法是一个表,则重复 1、2、3;如果 __index 方法是一个函数,则返回该函数的返回值。
实例
mytable = setmetatable({key1 = "value1"}, {
__index = function(mytable, key)
if key == "key2" then
return "metatablevalue"
else
return nil
end
end
})
print(mytable.key1,mytable.key2)
Output
value1 metatablevalue
实例解析
- mytable 表赋值为 {key1 = “value1”}。
- mytable 设置了元表,元方法为 __index。
- 在mytable表中查找 key1,如果找到,返回该元素,找不到则继续。
- 在mytable表中查找 key2,如果找到,返回 metatablevalue,找不到则继续。
- 判断元表有没有__index方法,如果__index方法是一个函数,则调用该函数。
- 元方法中查看是否传入 “key2” 键的参数(mytable.key2已设置),如果传入 “key2” 参数返回 “metatablevalue”,否则返回 mytable 对应的键值。
__newindex
步骤
在对新索引键赋值时,会调用元方法,而不进行赋值。而如果对已存在的索引键,则会进行赋值,而不调用元方法 __newindex。
实例
mytable = setmetatable({key1 = "value1"}, {
__newindex = function(mytable, key, value)
rawset(mytable, key, "\""..value.."\"")
end
})
mytable.key1 = "new value"
mytable.key2 = 4
print(mytable.key1,mytable.key2)
output
new value “4”
__call
function table_maxn(t)
local mn = 0
for k, v in pairs(t) do
if mn < k then
mn = k
end
end
return mn
end
mytable = setmetatable({10}, {
__call = function(mytable, newtable)
sum = 0
for i = 1, table_maxn(mytable) do
sum = sum + mytable[i]
end
for i = 1, table_maxn(newtable) do
sum = sum + newtable[i]
end
return sum
end
})
newtable = {10,20,30}
print(mytable(newtable))
output
70
__tostring
实例
mytable = setmetatable({ 10, 20, 30 }, {
__tostring = function(mytable)
sum = 0
for k, v in pairs(mytable) do
sum = sum + v
end
return "表所有元素的和为 " .. sum
end
})
print(mytable)
output
表所有元素的和为 60
操作符
__add -> ‘+’
__sub -> ‘-’
__mul -> ‘*’
__div -> ‘/’
__mod -> ‘%’
__unm -> ‘-’
__concat -> ‘…’
__eq -> ‘==’
__lt -> ‘<’
__le -> ‘<=’