lua元表元方法

来源:互联网 发布:网络攻击的种类是什么 编辑:程序博客网 时间:2024/06/04 01:22

参考

1.元表基础

1.基础

1.userdata类型和table类型的每个变量都可以设置一个元表
2.number、string等每个类型可设置一个元表,类型的所有变量共用这个元表
3.只有table在lua里可以设置元表,其他都必须在 C 语言里设置元表
4.string类型默认已经设置元表了,通过 getmetatable(‘aa’) 查看

2.元表设置和读取

local a = {}local b = {}local meta = {}查看变量元表getmetatable(变量)设置变量元表1.正常设置 setmetatable(a, meta)2.设置元表是自己 setmetatable(a, a)3.元表相互设置出错  setmetatable(a, b)  setmetatable(b, a)

2.元方法

local a = {}local b = {}local meta = {}local c = a + b             --__addsetmetatable(a, meta)       --__metatableprint(a)                    --__tostringprint(a.xx)                 --__indexa.xx = 5                    --__newindex

1.数学运算符重载

__add 元方法

说明:两个table变量是不能做算术运算的比如,如 tab1+tab2,通过运算符重载实现两个table算术运算
用途:运算符重载

local a = {}local b = {}local meta = {}meta.__add = function(p1, p2)    print('p1 == a')    print('p2 == b')    return 100endsetmetatable(b, meta)local c = a + b         --c==100

1.先检查a变量是否有元表和元方法__add,如果a有不再检查b了,如果a没有再去检查b
2.形参p1对应变量a,p2对应变量b
3.变量a或b只要有一个有元表并且有元方法__add,另一个可以是任何类型

table其他算术运算重载(*、/、-)类似 “+”(__add) 法

2. __tostring

local b = {}local meta = {}meta.__tostring = function(p)    return "aa"endsetmetatable(b, meta)print(b)    --打印:aa

1.执行 print 检查 b 是否有元表并且有元方法 __tostring
2.有打印元方法 __tostring 返回的值

3. __metatable

表 b 已经设置过元表了,不能给表 b 再次设置元表
不能得到表 b 的元表

local b = {}local meta = {}meta.__metatable = '不能获得元表了'setmetatable(b, meta)print(getmetatable(b))  -- 打印:不能获得元表了setmetatable(b, {})     -- 报错

0.前提:变量 b 有元表并且 __metatable 字段不为nil
1.getmetatable 得到变量 b 元表,打印 __metatable 字段内容
2.setmetatable 设置变量 b 元表,变量 b 已经有元表了不能再设置元表了

4. __index

触发:访问表 b 里不存在的字段 xx

local b = {}local meta = {}setmetatable(b, meta)-- meta.__index = function(tab, key)--  return 'aaa'-- endmeta.__index = {xx='aaa'}print(b.xx)     --打印:aaa

1.查找表 b 的元表 meta, meta 对应的字段 __index
2.如果 __index 对应的是函数, b.xx 等于函数返回值
3.如果 __index 对应的是table, b.xx 去 table 里查找 xx 字段返回对应的值
4.读取表没有的字段 rawget(table, key)(不考虑元表) 不会执行 __index

5. __newindex

触发:给表 b 添加新的字段 xx 并给它赋值
用途:不希望给表 b 在增加新的字段

local b = {}local meta = {}setmetatable(b, meta)meta.__newindex = function(table, key, value)    print('执行了')    endb.xx = 'bbb'print(b.xx)     --打印:nil

1.给表 b 的新字段 xx 赋值
2.执行表 b 的元表 meta 对应的字段 __newindex 的方法
3.表添加新字段并赋值 rawset(table, key, value)(不考虑元表) 不会执行 __newindex