1、介绍
表的功能十分有限,使用元表可以改变表的行为从而增加表的功能,例如两个表相加。
2、设置元表
setmetatable方法用于设置表和元表的关联
getmetatable返回对象的元表
Ttab = {} --普通表
Metatab = {} --元表
print(setmetatable(Ttab,Metatab))
print(Ttab)
从输出可见,通过setmetatable设置元表将返回和普通表相同的一个表
print(Metatab)
print(getmetatable(Ttab))
3、元表中的方法
(1)__index
当访问表的键时,没有对应键,则表将访问元表中的__index方法,该方法可以为一个表或者为函数。在元表中__index可以看作为一个键,其处理的是普通表没有设置键的值。
Ttab = {} --普通表
Metatab = {} --元表
Metatab = {__index = function (Ttab,key)
if key == "hong" then
return "hello hong"
else
return "bye"
end
end
}
Ttab = {ming = "hello ming"}
Ttab = setmetatable(Ttab,Metatab) --设置元表
print(Ttab.ming)
print(Ttab.marry)
print(Ttab.hong)
print(Ttab.liu)
访问顺序:
普通表访问“ming”,找到对应值并返回为“hello ming”
普通表访问“marry”,普通表中没有对应键,所以访问元表中的__index方法,其方法对应的是一个函数,Ttab表示普通表,key为传入的键,当前键不满足条件则返回“bye”
普通表访问“hong”,当前普通表不存在该键,则访问元表中的__index方法,该键满足条件所以返回""hello hong"
普通表访问“liu”,当前普通表不存在该键,则访问元表中的__index方法,该键不满足条件所以返回"bye"
Ttab = {} --普通表
Metatab = {} --元表
otherTab = {marry = "hello marry",hong = "hello hong"} --用于__index访问的表
Metatab = {__index = otherTab}
Ttab = {ming = "hello ming"}
Ttab = setmetatable(Ttab,Metatab) --设置元表
print(Ttab.ming)
print(Ttab.marry)
print(Ttab.hong)
print(Ttab.liu)
在__index指定的表中存在marry和hong索引,则当普通表访问到没有的索引时,则访问元表中__index对应的表
(2)__newindex
当为表添加的新的键值时,将会调用元表__newindex方法,该方法可以对应表或者函数。
Ttab = {} --普通表
Metatab = {} --元表
otherTab = {} --用于__newindex访问的表
Metatab = {__newindex = otherTab}
Ttab = {ming = "hello ming"}
Ttab = setmetatable(Ttab,Metatab) --设置元表
Ttab.hong = "hello hong"
print(Ttab.ming)
print(Ttab.hong)
print(otherTab.hong)
由运行结果可以看出,当为普通表添加新的键值时,赋值时在普通表,但真正访问时却在otherTab表中,因为在元表中__newindex方法指定了otherTab表,所以在为普通表更新键值时,更新的键值将添加至__newindex指定表中
Ttab = {} --普通表
Metatab = {} --元表
Metatab = {__newindex = function (tab,key,value)
rawset(Ttab,key,value)
end}
Ttab = {ming = "hello ming"}
Ttab = setmetatable(Ttab,Metatab) --设置元表
Ttab.hong = "hello hong"
print(Ttab.ming)
print(Ttab.hong)
元表中的__newindex方法指定为一个函数,tab表示传入的表,key键,value值,使用rawset函数更新传入的表的内容
(3)添加运算符
当实现表+表时,直接使用将会出现报错,使用元表定义操作符可以有效处理
__add 对应操作符+
__sub 对应操作符-
__mul 对应操作符*
__div 对应操作符/
__mod 对应操作符%
__unm 对应操作符-
__concat 对应操作符...
__eq 对应操作符==
__lt 对应操作符<
__le 对应操作符<=
__gt 对应操作符>
以下以__add为例子,实现两张表对应位数值相加
Ttab = {} --普通表
Metatab = {} --元表
Ytab = {} --普通表
Metatab = {__add = function(tab,newtab)
if #tab == #newtab then
for i =1 ,#tab do
tab[i] = tab[i]+newtab[i]
end
end
end}
Ttab = {10,20,30}
Ytab = {20,30,40}
Ttab = setmetatable(Ttab,Metatab) --设置元表
temp = Ttab+Ytab
for k,v in pairs(Ttab) do
print(k,v)
end
(4)__call
该方法意思为,当将表像函数调用时,将会调用__call对应的方法
Ttab = {} --普通表
Metatab = {} --元表
Metatab = {__call = function(tab,arg)
print(arg)
return "Ttab"
end}
Ttab = setmetatable(Ttab,Metatab) --设置元表
str = Ttab(69)
print(str)
tab表示传入的表,arg表示传入参数
(5)__tostring
当表作为字符串使用时,将调用tostring对应的方法
Ttab = {} --普通表
Metatab = {} --元表
Metatab = {__tostring = function (tab)
local str = ""
for k,v in pairs(tab) do
str = str..v.." "
end
return str
end}
Ttab = {"ming,hong,wang,marry"}
Ttab = setmetatable(Ttab,Metatab) --设置元表
print(Ttab)