metatable是一个表,它有助于在密钥集和相关元方法的帮助下修改附加到的表的行为.这些元方法是强大的Lua功能,可以启用功能:
更改/添加功能到表上的运算符.
使用metatable中的__index表中的密钥不可用时查找元表.
处理元表时有两个重要的方法,包括 :
setmetatable(table,metatable) : 此方法用于为表格设置元表.
getmetatable(table) : 此方法用于获取表的元表.
让我们首先看一下如何将一个表设置为另一个表的元表.它显示如下.
mytable = {}mymetatable = {}setmetatable(mytable,mymetatable)
上面的代码可以用一行表示,如下所示.
mytable = setmetatable({},{})
_index
一个简单的metatable示例,用于查找表中没有的元表如下所示.
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)
当我们运行上述程序时,我们无线我将得到以下输出.
value1 metatablevalue
让我们解释一下上面的例子中步骤发生了什么.
这里的表格是 {key1 ="value1"} .
为mytable设置了Metatable,其中包含__index的函数,我们将其称为元方法.
metamethod执行查找索引"key2"的简单工作,如果找到它,则返回"metatablevalue",否则返回相应索引的mytable值.
我们可以拥有上述程序的简化版本,如下所示.
mytable = setmetatable({key1 = "value1"}, { __index = { key2 = "metatablevalue" } })print(mytable.key1,mytable.key2)
__ newindex
当我们将__newindex添加到metatable时,如果表中没有键,则行为新密钥的vior将由元方法定义.下面给出了当主表中没有索引时设置metatable索引的简单示例.
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)
当你运行上面的程序时,你得到以下输出.
value1nilnew value 2new value 1nil
您可以在上面的程序中看到,如果是key存在于主表中,它只是更新它.当维护中的密钥不可用时,它会将该密钥添加到元表中.
使用rawset函数更新同一个表的另一个示例如下所示.
mytable = setmetatable({key1 = "value1"}, { __newindex = function(mytable, key, value) rawset(mytable, key, ""..value.."") end})mytable.key1 = "new value"mytable.key2 = 4print(mytable.key1,mytable.key2)
当我们运行上述程序时,我们将得到以下输出.
new value"4"
rawset设置值而不使用metatable的__newindex.类似地,rawget在不使用__index的情况下获取值.
向表添加运算符行为
使用&plus组合两个表的简单示例;运算符显示在下方 :
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 + secondtablefor k,v in ipairs(mytable) do print(k,v)end
当我们运行上述程序时,我们将获得以下输出.
112233445566
__add键包含在metatable添加operator+的行为.键表和相应的运算符如下所示.
Sr.No. | Mode&说明 |
---|---|
1 | __add 更改运算符'+'的行为. |
2 | __ sub 更改运营商的行为' - '. |
3 | __ mul 更改运算符'*'的行为. |
4 | __ div 更改运算符'/'的行为. |
5 | __ mod 更改运营商'%'的行为. |
6 | __ unm 更改运算符' - '的行为. |
7 | __ concat 更改运算符'..'的行为. |
8 | __ eq 更改运营商的行为'=='. |
9 | __ lt 更改运算符'<'的行为. |
10 | __ le 更改运算符'< ='的行为. |
__ call
使用__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语句的行为,我们可以使用__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
如果你完全了解元表的功能,那么你可以真正执行很多非常复杂的操作而不使用它.因此,尝试使用元表中可用的不同选项的元表进行更多工作,如示例中所述,并创建自己的样本.