脚本小子_Lua元表例子

一、Lua元表例子
1、table的__index例子解析
1.1、__index例子1
  • 代码
local t = {'a','b'}
-- 打印t所具有的key
print(t[1])
print(t[2])
-- 打印t所具不具有的key
print(t[3])

-- 设置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])
  • 解析过程:
    • 程序从上往下执行,遇到print函数,分别打印'a','b'。因为table t没有索引3的值,所以打印nil
    • 设置table t的__index属性元表
    • 打印t[3],lua先检查t是否存在,如存在则直接返回对应的值。相反则检查t是否设置__index,如无则返回nil
如有,则根据__index所设置的值进行处理,当前该值为一个函数,因此就回调该函数,该函数接收两个参数,一个值table本身,另一个是索引值。
1.2、__index例子2
  • 代码
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])
  • 解析过程
    • 根据setmetatable的参数格式,单独定义了一个table,获取的值则根据上面的说明执行
1.3、__index例子3
  • 代码
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

猜你喜欢

转载自blog.csdn.net/u014795720/article/details/80217618
今日推荐