开发手册 欢迎您!
软件开发者资料库

Lua - Metatables

Lua Metatables - 从简单和简单的步骤学习Lua编程语言,从基本到高级概念,包括概述,环境设置,基本语法,变量,数据类型,运算符,循环,决策,函数,字符串,数组,迭代器,表,模块,Metatables,协同程序,文件I / O,错误处理,调试,垃圾收集,面向对象,Web编程,数据库访问,游戏编程及其标准库。

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


如果你完全了解元表的功能,那么你可以真正执行很多非常复杂的操作而不使用它.因此,尝试使用元表中可用的不同选项的元表进行更多工作,如示例中所述,并创建自己的样本.