目录
- 一、元表
- 二、元表的设置
- 1、类型的原始元表
- 2、设置元表和获取元表
- 2-1、setmetatable(table, metatable)
- 2-2、getmetatable(object)
- 2-3、举个例子
- 三、元表方法
- 1、具有的元方法
- 1-1、算术运算符
- 1-2、关系运算符
- 1-3、库相关方法
- 1-4、表相关方法
- 2、元方法的搜索
- 3、举个例子
- 四、写在最后
一、元表
元表可以修改一个值在面对一个未知操作时的行为,Lua 中使用 table 作为元表的承载。
元表只能给出预先定义的操作集合的行为,比类会更加受限制,不支持继承。
Lua 每一个值都可以有元表 :
- 表和用户数据类型都具有各自独立的元表;
- 其他类型的值则共享对应类型所属的同一个元表;
二、元表的设置
1、类型的原始元表
Lua 中,元表的设置只能针对 table ,其他类型都不能设置。
table 的初始化元表为 nil ,即没有设置元表,只能通过 setmetatable 进行设置,多个 table 可以共享一个 table 作为元表(当然也可以使用他自己作为自己的元表,因为他自身也是一个 table)
Lua 只有 string 初始化了元表,而且是针对了所有的字符串,即 string 都是同一个元表。其他的类型为 nil 。
print(\”表的初始值\”, getmetatable({})) –> 表的初始值 nil
print(\”整型的初始值\”, getmetatable(10)) –> 整型的初始值 nil
print(\”浮点型的初始值\”, getmetatable(10.0)) –> 浮点型的初始值 nil
— 通过打印可以看到两个字符串的元表是同一个
print(\”字符串的初始值\”, getmetatable(\”江澎涌\”)) –> 字符串的初始值 table: 0x600000b14640
print(\”字符串的初始值\”, getmetatable(\”jiangpengyong\”)) –> 字符串的初始值 table: 0x600000b14640
print(\”布尔型的初始值\”, getmetatable(true)) –> 布尔型的初始值 nil
print(\”nil的初始值\”, getmetatable(nil)) –> nil的初始值 nil
function sayHello() end
print(\”函数的初始值\”, getmetatable(sayHello)) –> 函数的初始值 nil
2、设置元表和获取元表
2-1、setmetatable(table, metatable)
给表 table 设置元表 metatable
参数
- table:要被设置元表的表
- metabale:元表,如果值为 nil ,则表明要删除 table 的原有元表。如果原来的元表有 __metatable 字段,则不能再设置元表,否则会抛出异常 cannot change a protected metatable
__metatable 会在下面的 “表相关方法” 小节分享
返回值:
返回被设置元表的表,就是参数 table
2-2、getmetatable(object)
如果 object 没有元表,则返回 nil
如果对象 Object 有元表,且该元表有一个 "__metatable" 字段,则返回关联的值。否则,返回给定对象 Object 的元表
2-3、举个例子
local oriTable = {}
local metaTable = {}
print(setmetatable(oriTable, metaTable), oriTable, metaTable) –> table: 0x600001ac0840 table: 0x600001ac0840
print(getmetatable(oriTable), metaTable) –> table: 0x600001ac0900 table: 0x600001ac0900
给元表带有__metatable字段的表,设置新的元表,则会抛出异常(见下图)
t2 = { c = 1 }
t2.__metatable = { a = 1 }
s1 = {}
setmetatable(s1, t2)
print(\’getmetatable(s1)[\”a\”]\’, getmetatable(s1)[\”a\”]) –> getmetatable(s1)[\”a\”] 1
— 此处会抛出异常:cannot change a protected metatable
print(setmetatable(s1, {}))
三、元表方法
1、具有的元方法
元表方法方法很像 kotlin 中的操作符方法
1-1、算术运算符
1-2、关系运算符
值得注意: ~=、a > b、a >= b 没有对应的元方法,会被转为如下
- a ~= b 会被转为 not( a == b)
- a > b 会被转为 b < a
- a >= b 会被转为 b <= a
关系运算符遇到两个不同类型的对象,则会直接返回 false ,不会进行搜寻任何的元方法
1-3、库相关方法
1-4、表相关方法
__index 和 __newindex 的异同
- 相同点:两个函数都是发生在 table 中没有对应的 key 时触发
- 不同点:当前需要的索引没有对应的值时则调用 __index ,如果 table 设置值时,则调用 __newindex
2、元方法的搜索
如果两个变量相加,搜索规则如下:
- 先查看第一个值是否有元表,并且是否存在所需元方法,如果存在则使用该元方法,此时第二个值的元方法被忽略。否则进入下一条
- 查看第二个值是否有元表,并且是否存在所需的元方法,如果有则进行使用。否则进入第三条
- 抛出异常
3、举个例子
这里元方法比较多,就不一一粘贴代码了,不然会让文章非常冗长。建议各位童鞋们移步 github clone 下代码自行运行一下会更加深刻理解。
“算术运算符” 、 “关系运算符”、“库相关方法” 相关的代码 可以查看以下的代码:
集合.lua:github.com/zincPower/l…
集合调用.lua:github.com/zincPower/l…
“表相关方法” 相关的代码
表相关元方法.lua:github.com/zincPower/l…
四、写在最后
以上就是详解Lua中的元表和元方法的详细内容,更多关于Lua元表和元方法的资料请关注悠久资源网其它相关文章!
您可能感兴趣的文章:
- 举例说明Lua中元表和元方法的使用
- Lua教程(九):元表与元方法详解
- Lua中的元表和元方法学习笔记
- Lua中的元表与元方法学习总结
- Lua元表与元方法实例讲解
- Lua中使用元表(metatable)执行算术类元方法实例