1. Lua metatable example
1. Analysis of table's __index example
1.1, __index example 1
- code
local t = {'a','b'}
-- print the key that t has
print(t[1])
print(t[2])
-- print the key that t does not have
print(t[3])
-- set t __index
setmetatable(t,{__index = function(t,k)
for k,v in pairs(t) do
print (k, '=', v)
end
print(k)
end
})
print(t[3])
- Parsing process:
- The program executes from top to bottom, encounters the print function, and prints 'a' and 'b' respectively. Because table t has no value at index 3, it prints nil
- Set the __index attribute of table t to the meta table
- Print t[3], lua first checks whether t exists, and if so, returns the corresponding value directly. On the contrary, check if t is set to __index, if not, return nil
If there is, it is processed according to the value set by __index. The current value is a function, so the function is called back. The function receives two parameters, one is the value of the table itself, and the other is the index value.
1.2, __index example 2
- code
local t = {'a','b','c'}
local m = {}
setmetatable(t,m)
-- print(getmetatable(t) == m)
m.__index = function(t,k)
for k,v in pairs(t) do
print (k, '=', v)
end
print(k)
end
print(t[4])
- parsing process
- According to the parameter format of setmetatable, a table is defined separately, and the obtained value is executed according to the above description
1.3, __index example 3
- code
local t = {'a','b','c'}
setmetatable(t,{
__index = function(t,k)
for k,v in pairs(t) do
print (k, '=', v)
end
print(k)
end
})
local t1 = {x=1,y=2}
setmetatable(t1,{__index=t})
print(t1.x)
print(t1[1])
- 解析过程
- 从这几个例子可以看出,__index元方法不一定是函数,它还可以是table类型。当其是函数时,则lua将table和索引k作为参数来调用该函数。而当它是table时,lua则以相同的方式来重新访问这个table
2、table __newindex例子
2.1、__newindex例子1
- 代码
local t = {'a','b'}
setmetatable(t,{
__index = function(t,v)
print(k)
end,
__newindex = function(t,k,v)
t[k] = v
print(k,v)
end
})
print(t[2])
t[2] = 'c'
print(t[2])
t[3] = 'c'
- 解析过程
- 程序运行出错。原因是table设置了__newindex,因此在回调函数中执行t[k]=v,时又回调__newindex,从而进入死循环
2.2、__newindex例子2
- 代码
local t = {'a','b'}
setmetatable(t,{
__index = function(t,v)
print(k)
end,
__newindex = function(t,k,v)
rawset(t,k,v)
end
})
print(t[2])
t[2] = 'c'
print(t[2])
t[3] = 'c'
for k,v in pairs(t) do
print(k,'=',v)
end
- 解析过程
- 当程序执行t[3]='c'时,由于t中不存在索引3,因此触发__newindex元方法。传入三个参数,t本身、新的索引k,和其对应的值v。再执行rawset,对t本身赋值。就可以确保不会死循环调用__newindex