Script kiddie _Lua metatable example

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325647715&siteId=291194637