谁能告诉我为什么 code1 和 code2 有不同的结果,而 code3 和 code4 有相同的结果。
代码1:
o = {x = "hi"}
mt = {}
mt.__gc = function (o) print(o.x) end
setmetatable(o, mt)
o = nil
collectgarbage()
Run Code Online (Sandbox Code Playgroud)
代码1的结果:
你好
代码2:
o = {x = "hi"}
mt = {}
setmetatable(o, mt)
mt.__gc = function (o) print(o.x) end
o = nil
collectgarbage()
Run Code Online (Sandbox Code Playgroud)
code2:nothing的结果
code1和code2唯一的区别就是语句setmetatable(o, mt)和语句mt.__gc = function (o) print(o.x) end的执行顺序不同。他们的结果完全不同:第一个打印 hi 而另一个什么都不打印。将元表设置为对象的顺序最终会影响结果吗?如果是,为什么 code3 和 code4 有相同的结果?
代码3
o = {x = "hi"}
mt = {}
setmetatable(o, mt)
mt.__index = function () print("no such key") end
print(o["x"])
print(o["y"])
Run Code Online (Sandbox Code Playgroud)
代码4
o = {x = "hi"}
mt = {}
mt.__index = function () print("no such key") end
setmetatable(o, mt)
print(o["x"])
print(o["y"])
Run Code Online (Sandbox Code Playgroud)
code3和code4的结果都是一样的:
嗨,
没有这样的关键
零
从 Lua 5.2 开始,Lua 表支持元方法 __gc。引用第二段:
对于要在收集时完成的对象(表或用户数据),您必须将其标记为完成。在设置元表时将对象标记为完成,并且元表有一个由字符串“
__gc”索引的字段。请注意,如果您设置一个没有__gc字段的元表,然后在元表中创建该字段,则该对象将不会被标记为完成。
这正是你的情况:第二句话描述了第一个例子,第三个,第二个。