(一)元表的概念
–任何表变量都可以作为另一个表变量的元表
–任何表变量都可以有自己的元表
–有元表的那张表相当于子表
–作用:当对子表进行一些特定操作时,会执行元表中的内容
(二)设置元表
--如何设置元表
metatable={}
mytable={}
--第一参数子表,第二个参数元表
setmetatable(mytable,mytable)
(三)元表的特定操作
(1)元表的特定操作_tostring,把子表当成某个设定好的特定字符串
--元表的特定操作__tostring,把子表当成某个设定好的特定字符串,可以用作获取子表的名字
--注意这里是两根下划线
metatable3={
__tostring=function()
return "mytable3"
end
}
mytable3={
}
print(mytable3)--table: 0x7fbafe904b10,没设置元表浅,打印表的内存单元
setmetatable(mytable3,metatable3)
print(mytable3)--mytable3,设置了元表后,打印元表的__tostring返回的字符串
--修改元表,让其能打印子表中的属性
metatable4={
__tostring=function(t)
return t.name
end
}
mytable4={
name="hello"
}
setmetatable(mytable4,metatable4)
print(mytable4)--hello,注意这里调用__tostring,并没有传参数
--所以这样写是默认调用__string(metable4)
(2)元表的特定操作_call,把子表当成一个特定的函数使用时,用元表里的__call函数
且默认的第一个参数是子表本身
--元表的特定操作__call
--当子表被当作一个函数来使用时,会默认调用__call中的内容,默认的第一个参数是子表本身
metatable5={
__tostring=function(t)
return t.name
end,
__call=function(a)--这里有个默认参数是子表
print(a.sex)
print("__call fun")
end
}
mytable5={
name="hello",
sex="false"
}
setmetatable(mytable5,metatable5)
print(mytable5)
--把表作为函数用时
mytable5()--false __call fun,调用了元表里的__call方法,并把子表本身作为了默认的第一个参数
(3)元表的特定操作运算符重载
–元表的特定操作运算符重载
–也就是说通过元表可以定义表之间的运算,__add,__sub,__mul,__div,_mod(取余),_pow(幂),_eq(),_lt(<),_le(<=),_concat(拼接)
–如果要用条件运算符(如:_eq(),_lt(<),_le(<=))来比较两个表对象,那么这两个表对象的元表要一致,才能比较
--元表的特定操作运算符重载
--也就是说通过元表可以定义表之间的运算,__add,__sub,__mul,__div,_mod(取余),_pow(幂)
--_eq(==),_lt(<),_le(<=),_concat(拼接)
metatable7={
__add=function(t1,t3)
return t1.age+t3.age
end
}
mytable7={age=4}
mytable8={age=5}
setmetatable(mytable7,metatable7)
print(mytable7+mytable8)--9,用的是元表里__add的运算
(4)元表的特定操作_index
–当子表中找不到某个变量时,回到元表的__index指定的表中去寻找该变量
–而且__index最好写在表外面,写里面有的时候不正确
–而且__index还可以一层层往上找
--元表的特定操作__index
--当子表中找不到某个变量时,回到元表的__index指定的表中去寻找该变量
metatable8={}
mytable8={}
testtable={age=13}
setmetatable(mytable8,metatable8)
metatable8.__index=testtable--将元表的__index指向的表指向了testtable
metatable8.__index={age=14}--这种写法也可以
print(mytable8.age)--13
(5)元表的特定操作_newIndex
--元表的特定操作__newIndex
--当赋值时,如果赋值一个不存在的索引,那么会把这个值赋值到newindex所指的表中,不会修改自己
--相当于把值设置给了元表,而不是子表自己?
mytable10={}
metatable10={}
metatable10.__newindex={}
setmetatable(mytable10,metatable10)
mytable10.age=13--相当于给mytable表里添加了一个age属性
print(mytable10.age)--但是这里打印的事nil
print(metatable10.__newindex.age)--13
(6)获取元表
print(getmetatable(mytable10))--table: 0x7f96fa908a90
(7)只在自己的表中找,不去元表找,绕开__index
mytable={age=1}
print(rawget(mytable,"age"))
(8)只给自己的表中的元素设置值,不会设置元表,绕开__newIndex
mytable={age=1}
print(rawget(mytable,"age"))--1
rawset(mytable,"age",3)
print(mytable.age)--3