Lua,关于__gc设置顺序的问题

Pho*_*hao 5 lua

谁能告诉我为什么 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的结果都是一样的:

嗨,
没有这样的关键

Ale*_*hin 5

从 Lua 5.2 开始,Lua 表支持元方法 __gc。引用第二段:

对于要在收集时完成的对象(表或用户数据),您必须将其标记为完成。在设置元表时将对象标记为完成,并且元表有一个由字符串“ __gc”索引的字段。请注意,如果您设置一个没有__gc字段的元表,然后在元表中创建该字段,则该对象将不会被标记为完成。

这正是你的情况:第二句话描述了第一个例子,第三个,第二个。