首页 > 解决方案 > Lua,关于设置__gc的顺序问题

问题描述

谁能告诉我为什么 code1 和 code2 有不同的结果,但 code3 和 code4 有相同的结果。
代码1:

o = {x = "hi"}
mt = {}
mt.__gc = function (o) print(o.x) end
setmetatable(o, mt)
o = nil
collectgarbage()

代码1的结果:

你好

代码2:

o = {x = "hi"}
mt = {}
setmetatable(o, mt)
mt.__gc = function (o) print(o.x) end
o = nil
collectgarbage()

code2:nothing
的结果code1和code2的唯一区别就是statementsetmetatable(o, mt)和statementmt.__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"])

代码4

o = {x = "hi"}
mt = {}
mt.__index = function () print("no such key") end
setmetatable(o, mt)
print(o["x"])
print(o["y"])

code3 和 code4 的结果都是一样的:


,没有这样的密钥
nil

标签: lua

解决方案


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

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

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


推荐阅读