setmetatable备忘


访问对象的成员, 如果成员不存在, 去metatable对象的__index上去找, 而不是直接去metatable对象上找

1 local a = {}
2 local mt = { str="123" }
3 setmetatable(a, mt)
4 
5 print(a.str) --这边是nil, 因为不是在metatable对象本身上面找

 下面的是对的

1 local a = {}
2 local mt = { str="123" }
3 mt.__index = mt --是在metatable的对象的__index上找
4 setmetatable(a, mt)
5 
6 print(a.str) --这样就对了

也可以这样

local a = {}

local mt = { str="123" }
a.__index = mt
setmetatable(a, a)

或者这样 

1 local a = {}
2 
3 local mt = { str="123" }
4 setmetatable(a, { __index = mt })

__newindex也是如此,设置对象的成员时, 如果成员不存在, 则到metatable对象的__newindex上去设置, 而不是直接在metatable对象上设置

 1 local a = {}
 2     
 3 local mt = { str="123" }
 4 setmetatable(a, mt)
 5 
 6 a.str = "456"
 7 print(mt.str) --这边是123, 因为metatable的__newindex此时还是nil
 8 
 9 mt.__newindex = mt
10 a.str = nil
11 a.str = "456" --成员不存在, 到metatable对象的__newindex上去设置
12 print(mt.str) --这边metable就被改掉了
lua