元表
元表用于重载语言中的常见操作。这些操作可以包括加法、乘法、相等比较和(顾名思义)类似表的操作,例如通过键访问值table[key]
。
元表通常用于在 Lua 中实现面向对象的编程。驱动它的主要机制是使用__index
. 这个例子将以最基本的形式说明这一点:
>>> parent = {parentID = 'Secret'}
>>> child = {}
>>> setmetatable(child,{__index=parent})
>>> =child.parentID
Secret
密钥parentID
实际上并不存在于 child 中,因此child 中没有类似以下内容:
child = {
parentID = 'Secret'
}
相反,我们已经做到了,当有人在寻找不存在的键时child
,我们去查看parent
,这是在我们分配给 table in的元表中设置的:
>>> setmetatable(child,{__index=parent})
因此,当我们要求时,以编程方式的事件流child.parentID
是:
- 是否
child
包含一个键值对,哪个键是"parentID"
?不,因此转到 2。
- 是否
child
已__index
在它的元表中定义?是的,转到 3。
- 查看引用的表
__index
以检查密钥"parentID"
- 在父母身上找到!返回的值
parent["parentID"]
所以这允许我们在表之间创建关系。我们可以使用__index
metatable 方法在代表所有玩家信息的表格和每个玩家自己之间建立关系,如下所示:
Player = { }
Player_metatable = {
__index = Player --look for the missing key in the Player table
}
function Player.new(name)
aPlayer = { name = name }
setmetatable(aPlayer,Player_metatable)
return aPlayer
end
function Player:rotate()
print("I'M ROTATING",tostring(self))
end
henry = Player.new("Henry")
henry:rotate()
当我们调用时,Player.new("Henry")
我们创建一个表,并将其元表设置为Player_metatable
,就像child
在第一个示例中设置元表一样。但是,我们只是在函数内部而不是直接在 bat 中执行,没有区别!
当我们调用上面概述的情况时,我们会在 中henry:rotate()
查找一个键,但没有找到,所以我们查找(因为那是指向我们元表中的表)。我们有一个与该键关联的函数。因此,我们然后调用该函数,由于语法而将自己传入。"rotate"
henry
Player
__index
t:function
要创建一个类的实例,您只需要分配一个表,元表指向您拒绝类行为的表。所以我们可以创建任意数量的玩家:
my_player_name = Player.new(...)
修改Player
表中的值,将反映在具有关联元表的所有表中。