Lua 元表
正如其名,元表也是表。不过,将元表与表相关联后,我们就可以通过设置元表的键和相关方法来改变表的行为。元方法的功能十分强大,使用元方法可以实现很多的功能,比如:
- 修改表的操作符功能或为操作符添加新功能(译注:如果您学过 C++ 之类的面向对象的语言,应该比较好理解,其实它实现的是操作的重载)。
- 使用元表中的 __index 方法,我们可以实现在表中查找键不存在时转而在元表中查找键值的功能。
Lua 提供了两个十分重要的用来处理元表的方法,如下:
- setmetatable(table,metatable):此方法用于为一个表设置元表。
- getmetatable(table):此方法用于获取表的元表对象。
首先,让我们看一下如何将一个表设置为另一个表的元表。示例如下:
1 | mytable = {} |
mytable = setmetatable({},{})
1 |
|
mytable = setmetatable({key1 = “value1”}, {
__index = function(mytable, key)
if key == “key2” then
return “metatablevalue”
else
return mytable[key]
end
end
})
print(mytable.key1,mytable.key2)
1 |
|
value1 metatablevalue
1 |
|
mytable = setmetatable({key1 = “value1”}, { __index = { key2 = “metatablevalue” } })
print(mytable.key1,mytable.key2)
1 |
|
mymetatable = {}
mytable = setmetatable({key1 = “value1”}, { __newindex = mymetatable })
print(mytable.key1)
mytable.newkey = “new value 2”
print(mytable.newkey,mymetatable.newkey)
mytable.key1 = “new value 1”
print(mytable.key1,mymetatable.newkey1)
1 |
|
value1
nil new value 2
new value 1 nil
1 |
|
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)
1 |
|
new value “4”
1 |
|
mytable = setmetatable({ 1, 2, 3 }, {
__add = function(mytable, newtable)
for i = 1, table.maxn(newtable) do
table.insert(mytable, table.maxn(mytable)+1,newtable[i])
end
return mytable
end
})
secondtable = {4,5,6}
mytable = mytable + secondtable
for k,v in ipairs(mytable) do
print(k,v)
end
1 |
|
1 1
2 2
3 3
4 4
5 5
6 6
1 |
|
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))
1 |
|
70
1 |
|
mytable = setmetatable({ 10, 20, 30 }, {
__tostring = function(mytable)
sum = 0
for k, v in pairs(mytable) do
sum = sum + v
end
return “The sum of values in the table is “ .. sum
end
})
print(mytable)
1 |
|
The sum of values in the table is 60
如果你完全掌握了元表的用法,你就可以实现很多看上面很复杂的操作。如果不使用元表,就不仅仅是看上去很复杂了,而是真的非常复杂。所以,多做一些使用元表的练习,并熟练掌握所有元表的可选项,这会让你受益匪浅。