Lua - 元表
元表是一个表,它可以借助键集和相关元方法帮助修改其所附加的表的Behave。这些元方法是强大的 Lua 功能,可以实现以下功能:
更改/添加表上运算符的功能。
当表中的键不可用时,使用元表中的 __index 查找元表。
有两种重要的方法用于处理元表,其中包括 -
setmetatable(table,metatable) - 此方法用于设置表的元表。
getmetatable(table) - 此方法用于获取表的元表。
我们首先看看如何将一个表设置为另一个表的元表。如下所示。
mytable = {} mymetatable = {} setmetatable(mytable,mymetatable)
上面的代码可以用一行表示,如下所示。
mytable = setmetatable({},{})
_指数
下面显示了一个简单的元表示例,用于在表中不可用时查找元表。
mytable = setmetatable({key1 = "value1"}, { __index = function(mytable, key) if key == "key2" then return "metatablevalue" else return nil end end }) print(mytable.key1, mytable.key2)
当我们运行上面的程序时,我们将得到以下输出。
value1 metatablevalue
让我们分步骤解释一下上面示例中发生的情况。
这里的表 mytable 是{key1 = "value1"}。
为 mytable 设置元表,其中包含 __index 的函数,我们将其称为元方法。
元方法做了一个简单的工作,查找索引“key2”,如果找到,则返回“metatablevalue”,否则返回 mytable 对应索引的值。
我们可以得到上述程序的简化版本,如下所示。
mytable = setmetatable({key1 = "value1"}, { __index = { key2 = "metatablevalue" } }) print(mytable.key1,mytable.key2)
__新索引
当我们将 __newindex 添加到元表时,如果表中没有可用的键,则新键的Behave将由元方法定义。下面给出了一个简单的例子,当主表中没有索引时,设置元表的索引。
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)
当您运行上述程序时,您将得到以下输出。
value1 nil new value 2 new value 1 nil
您可以在上面的程序中看到,如果主表中存在某个键,它只会更新它。当主表中某个键不可用时,它会将该键添加到元表中。
下面显示了使用 rawset 函数更新同一表的另一个示例。
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)
当我们运行上面的程序时,我们将得到以下输出。
new value "4"
rawset 设置值而不使用元表的 __newindex。类似地,rawget 可以在不使用 __index 的情况下获取值。
将操作员Behave添加到表中
使用 + 运算符组合两个表的简单示例如下所示 -
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 2 2 3 3 4 4 5 5 6 6
__add 键包含在元表中以添加运算符 + 的Behave。按键及对应操作符表如下所示。
先生。 | 模式及说明 |
---|---|
1 | __添加 更改运算符“+”的Behave。 |
2 | __sub 更改运算符“-”的Behave。 |
3 | __mul 更改运算符“*”的Behave。 |
4 | __div 更改运算符“/”的Behave。 |
5 | __mod 更改运算符“%”的Behave。 |
6 | __unm 更改运算符“-”的Behave。 |
7 | __concat 更改运算符“...”的Behave。 |
8 | __eq 更改运算符“==”的Behave。 |
9 | __lt 更改运算符“<”的Behave。 |
10 | __乐 更改运算符“<=”的Behave。 |
__称呼
添加方法调用的Behave是使用 __call 语句完成的。一个简单的示例,返回主表中的值与传递的表中的值之和。
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))
当我们运行上面的程序时,我们将得到以下输出。
70
__tostring
要更改 print 语句的Behave,我们可以使用 __tostring 元方法。下面显示了一个简单的示例。
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)
当我们运行上面的程序时,我们将得到以下输出。
The sum of values in the table is 60
如果您完全了解元表的功能,那么您确实可以执行许多在不使用它的情况下非常复杂的操作。因此,请尝试更多地使用元表以及元表中可用的不同选项(如示例中所述),并创建您自己的示例。