Lua中每个值都可具有元表。元表是普通的Lua表,定义了原始值在某些特定操作下的行
为。
getmetatable(t)只能设置table类型的对象为元表。
算术类的元方法:
当我们直接将两个table进行相加时,程序是通不过的。我们只需要新建一个table,添加元方法即可。
只要某个值中含有对应的元方法,那么就可以执行对应的运算。
各种算术操作符的元方法名字:
__add: 加法
__sub: 减法
__mul: 乘法
__div: 除法
__unm: 相反数
__mod: 取模
__pow: 乘幂
以加法为例:
local mt = {}
mt.__add = function(t1, t2)
print("两个table相加的时候会调用本函数")
end
local t1 = {}
local t2 = {}
setmetatable(t1, mt)
setmetatable(t2, mt)
local result = t1 + t2
元表的加减法:
local mt = {}
mt.__add = function(s1, s2)
if s1.sex == "boy" and s2.sex == "girl" then
print("家庭完美")
return "中奖了"
else
print("还好")
return "中奖了"
end
end
local s1 = {
name = "hwllo",
sex = "boy"
}
local s2 = {
name = "tror",
sex = "girl"
}
local mt1 = {}
--给两个表设置元表
setmetatable(s1, mt1)
setmetatable(s2, mt)
local result = s1 + s2
print(result)
注意事项:
1、如果函数中的第一个值有元表,那么就以这个元表为准。
2、否则,如果第二个值有元表,就用第二个值得元表
3、如果两个值都没有元表,或者没有对应的元方法,那么就会报错
4、如果两个都有元表,且元方法相同,实现不同,以第一个为主
2、关系类的方法
__eq: 等于
__lt: 小于
__le: 小于等于
3、_index的使用
在调用table不存在的字段时,会调用_index元方法
方法的目的:
查询
local t = {
name = "hello"
}
local t1 = {
age = 20,
sex = "boy"
}
local mt = {
第一种方式
__index = function()
print("没有此键")
end
第二种方式
-- __index = t1
}
setmetatable(t, mt)
-- print(t.age)
-- print(t.sex)
print(t.name)
4、__newindex的使用
如果newindex是一个函数,则给不存在的字段赋值时,会调用此函数
如果newindex是一个table表,则给不存在的字段赋值时,会直接给_newindex的table
赋值
local t = {
name = "hello",
sex = "boy"
}
local t1 = {
name = "world"
}
local mt = {
第一种方式
-- __newindex = function()
-- print("此键不存在")
-- end
第二种方式
__newindex = t
}
setmetatable(t1, mt)
print(t1.age)
t1.age = 200
print(t.age)
因为__newindex = t所以当函数t1中没有此键时,会在t中自动创建一个此键,并为其赋
值
5、忽略元表rawget
通过rawget函数可以忽略元表中的__index和__newindex,让他们失效
local person1 = {
name = "hello",
age = 30,
sex = "boy"
}
local person2 = {
name = "world",
}
local mt = {
-- __index = function()
-- print("没有此键")
-- end,
-- __newindex = function()
-- print("赋值成功")
-- end
__index = person1,
__newindex = person1
}
setmetatable(person2, mt)
-- print(person2.age)
-- person2.age = 50
-- print(person1.age)
print(rawget(person2, "name"))
print(rawget(person2, "age"))
--纯粹为person2添加键
rawset(person2, "age", 44)
print(person2.age)