1: Lua 提供了元表(Metatable),允许我们改变table的行为,每个行为关联了对应的元方法。
例如,使用元表我们可以定义Lua如何计算两个table的相加操作a+b。
当Lua试图对两个表进行相加时,先检查两者之一是否有元表,之后检查是否有一个叫"__add"的字段,若找到,则调用对应的值。"__add"等即时字段,其对应的值(往往是一个函数或是table)就是"元方法"。
语法:
- setmetatable(table,metatable): 对指定 table 设置元表(metatable),如果元表(metatable)中存在 __metatable 键值,setmetatable 会失败。
- getmetatable(table): 返回对象的元表(metatable)。
mytable = {"lua","C#","C++"} --普通表
myMetatable = {} --元表 元表扩展了普通表的行为
mytable = setmetatable(mytable,myMetatable) --用来设置元表
print(getmetatable(mytable))
2: 元方法的使用; 元方法是用来定义元表的行为
__index
1:第一种情况后接对应的方法:
mytable = {"lua","C#","C++"} --普通表
--元表 元表扩展了普通表的行为
myMetatable = {
__index = function(tab,key)
print("调用了元表中的方法")
-- body
end
}
mytable = setmetatable(mytable,myMetatable) --用来设置元表
--当访问普通表中的下标值时,可以访问的到,那么就返回对应值
print(mytable[1])
--当访问普通表中的下标值不存在时,这个时候就会去调用元方法,tab就是对应的普通表,key就是对应的下标值
print(mytable[10])
2:第二种情况接对应的表:
mytable = {"lua","C#","C++"} --普通表
myNewTable = {}
myNewTable[8] = "C"
myNewTable[9] = "PHP"
myNewTable[10] = "Python"
--元表 元表扩展了普通表的行为
myMetatable ={
__index = myNewTable
}
mytable = setmetatable(mytable,myMetatable) --用来设置元表
--当访问普通表中的下标值时,可以访问的到,那么就返回对应值
print(mytable[1])
--当访问普通表中的下标值不存在时,这个时候就会去调用元方法,tab就是对应的普通表,key就是对应的下标值
print(mytable[10]) --Python
__newindex
1:对应方法
--__newindex当我们对表的数据进行修改的时候,修改的是一个新的索引才会起作用
--当我们给表添加新的键值对的时候才会使用__newindex
mytable = {"lua","C#","C++"} --普通表
myMetatable = {
__newindex = function(tab,key,value)
print("我们要修改的key为"..key.."把这个key值修改为:"..value)
rawset(tab,key,value)
-- body
end
}
mytable = setmetatable(mytable,myMetatable)
mytable[1] = "C#"
mytable[5] = "Lua"
print(mytable[5])
3:为元表添加操作符
mytable = {"lua","java","C#","C++"}
myMetatable = {
__add = function(tab,tab1)
-- body
print("调用加法操作符")
local maxindex = 0
maxindex = #tab
for k,v in pairs(tab1) do
maxindex = maxindex + 1
table.insert(tab,maxindex,v)
end
end
}
mytable = setmetatable(mytable,myMetatable)
newtable = {"PHP","Python"}
c = mytable+newtable --必须要有接收表
for k,v in pairs(mytable) do
print(k,v)
end
__add 键包含在元表中,并进行相加操作。 表中对应的操作列表如下:(注意:__是两个下划线)
模式 | 描述 |
---|---|
__add | 对应的运算符 '+'. |
__sub | 对应的运算符 '-'. |
__mul | 对应的运算符 '*'. |
__div | 对应的运算符 '/'. |
__mod | 对应的运算符 '%'. |
__unm | 对应的运算符 '-'. |
__concat | 对应的运算符 '..'. |
__eq | 对应的运算符 '=='. |
__lt | 对应的运算符 '<'. |
__le | 对应的运算符 '<='. |
4:__call方法调用。调用值时调用
--__call 元方法在 Lua 调用一个值时调用
mytable = {"lua","java","C#"}
myMetatable = {
__call = function(tab,arg,arg2,arg3,arg4)
-- body
print("调用了Call方法",arg,arg2,arg3,arg4)
return "xxz"
end
}
mytable = setmetatable(mytable,myMetatable)
v = mytable(1,2,3)
print(v)
5:__tostring方法调用。_tostring 元方法用于修改表的输出行为。
--__call 元方法在 Lua 调用一个值时调用
mytable = {"lua","java","C#"}
myMetatable = {
__call = function(tab,arg,arg2,arg3,arg4)
-- body
print("调用了Call方法",arg,arg2,arg3,arg4)
return "xxz"
end,
--__tostring 元方法在修改表的输出行为
__tostring = function(tab)
-- body
a = ""
for k,v in pairs(tab) do
a = a ..v..","
end
return a
end
}
mytable = setmetatable(mytable,myMetatable)
v = mytable(1,2,3)
print(v)
print(mytable)