美文网首页
2018-03-26 lua中元表简介

2018-03-26 lua中元表简介

作者: songjk | 来源:发表于2018-03-26 15:24 被阅读0次

Lua中提供的元表是用于帮助Lua数据变量完成某些非预定义功能的个性化行为,如两个table的相加。假设a和b都是table,通过元表可以定义如何计算表达式a+b。当Lua试图将两个table相加时,它会先检查两者之一是否有元表,然后检查该元表中是否存在__add字段,如果有,就调用该字段对应的值。这个值就是所谓的“元方法”,这个函数用于计算table的和。

Lua中每个值都有一个元表。table和userdata可以有各自独立的元表,而其它数据类型的值则共享其类型所属的单一元表。缺省情况下,table在创建时没有元表

设置table中的元方法

我们可以使用setmetatable函数来设置或修改任何table的元表。

t1 = {}
setmetatable(t,t1)
assert(getmetatable(t) == t1)

任何table都可以作为任何值的元表,而一组相关的table也可以共享一个通用的元表,此元表将描述了它们共同的行为。一个table甚至可以作为它自己的元表,用于描述其特有的行为。在Lua代码中,只能设置table的元表,若要设置其它类型值的元表,则必须通过C代码来完成。

在元表中,每种算术操作符都有对应的字段名,除了上述的__add(加法)和__mul(乘法)外,还有__sub(减法)、__div(除法)、__unm(相反数)、__mod(取模)和__pow(乘幂)。此外,还可以定义__concat字段,用于描述连接操作符的行为。

元表还可以指定关系操作符的含义,元方法分别为__eq(等于)、__lt(小于)和__le(小于等于),至于另外3个关系操作符,Lua没有提供相关的元方法,可以通过前面3个关系运算符的取反获得。

除了上述基于操作符的元方法外,Lua还提供了一些针对框架的元方法,如print函数总是调用tostring来格式化其输出。如果当前对象存在__tostring元方法时,tostring将用该元方法的返回值作为自己的返回值

函数setmetatable和getmetatable也会用到元表中的一个字段(__metatable),用于保护元表,如:

local myTable = {}
local tttable = getmetatable(myTable )
tttable.__metatable = "lock"
tttable = getmetatable(myTable )

一旦设置了__metatable字段,getmetatable就会返回这个字段的值,而setmetatable将引发一个错误。

访问元方法

算术类和关系类运算符的元方法都为各种错误情况定义了行为,它们不会改变语言的常规行为。但是Lua还提供了一种可以改变table行为的方法。有两种可以改变的table行为:查询table及修改table中不存在的字段。

__index元方法:

当访问table中不存在的字段时,得到的结果为nil。如果我们为该table定义了元方法__index,那个访问的结果将由该方法决定。见如下示例代码:


Window = {}
Window.prototype = {x = 0, y = 0, width = 100, height = 100}
Window.mt = {} --Window的元表
function Window.new(o)
setmetatable(o,Window.mt)
return o
end
--将Window的元方法__index指向一个匿名函数
--匿名函数的参数table和key取自于table.key。
Window.mt.__index = function(table,key) return Window.prototype[key] end
--下面是测试代码:
w = Window.new{x = 10, y = 20}
print(w.width) --输出100
print(w.width1) --由于Window.prototype变量中也不存在该字段,因此返回nil。


最后,Lua为__index元方法提供了一种更为简洁的表示方式,如:Window.mt.__index = Window.prototype。该方法等价于上例中的匿名函数表示方法。相比而言,这种简洁的方法执行效率更高,但是函数的方法扩展性更强。
如果想在访问table时禁用__index元方法,可以通过函数rawget(table,key)完成。通过该方法并不会加速table的访问效率。

__newindex元方法:

和__index不同的是,该元方法用于不存在键的赋值,而前者则用于访问。当对一个table中不存在的索引赋值时,解释器就会查找__newindex元方法。如果有就调用它,而不是直接赋值。如果这个元方法指向一个table,Lua将对此table赋值,而不是对原有的table赋值。此外,和__index一样,Lua也同样提供了避开元方法而直接操作当前table的函数rawset(table,key,value),其功能类似于rawget(table,key)。

详细见文章:
http://www.jb51.net/article/65184.htm

相关文章

  • 2018-03-26 lua中元表简介

    Lua中提供的元表是用于帮助Lua数据变量完成某些非预定义功能的个性化行为,如两个table的相加。假设a和b都是...

  • Lua中元表的学习

    Lua本身没有面向对象的思想,但是可以根据表、元表、元方法来靠近它 一、元表与元方法的概念Lua中每个值都可具有元...

  • lua入门

    Lua 简介

  • lua简介

    C#与Lua的区别:(C#需要编译而lua不需要)C#只能在特定的操作系统中进行编译成dll文件,然后打包进安装包...

  • Lua简介

    虽然计算机可以做很多事情,但它不会思考,它需要接受系统化的指令来工作。大部分用户通过应用程序为计算机指派任务,软件...

  • Lua脚本学习

    1.Lua的简介

  • 学习常用链接

    //Lua Lua table详解 Lua 元表详解 云风博客 //Unity Unity知识点 栈和队列 Uni...

  • Lua 实现面向对象 (原创)

    要理解Lua是如何实现面向对象的。首先要熟悉Lua元表的相关知识,可以阅读我上一篇文章《Lua元表 (Metata...

  • Lua实现继承的方法

    lua通过元表实现继承 lua查找一个表元素的规则如下 1.在表中查找,如果找到,则返回这个元素 2.判断该表是否...

  • Lua 元表(Metatable)

    学习网站Lua 元表(Metatable)

网友评论

      本文标题:2018-03-26 lua中元表简介

      本文链接:https://www.haomeiwen.com/subject/cvglcftx.html