tl;dr 版本:如果垃圾收集元方法在 Lua 状态关闭期间访问全局变量,它是否安全?本地升值呢?
当 alua_State
被关闭时lua_close
,Lua 文档说所有对象都被删除。它说任何相关的垃圾收集元方法都保证被调用。
伟大的。
但是,在这种范式下,有两种可能的 GC 元方法用例是不确定的:
如果您有一个使用存储可收集值的局部变量的 GC 元方法怎么办。比如说,一个字符串、一个函数等。也就是说,你的 GC 元方法被定义为:
local some_string = "string" function mt:__gc() --[[Do something with some_string]] end
在这种情况下会发生什么?是否有可能
some_string
被收集?我知道如果在正常情况下正在收集元表所在的对象,那么这是不可能的。Lua 会保证 的值some_string
会一直保持到 GC 函数本身被收集为止。但是由于所有对象都被 销毁
lua_close
,是否有可能在函数被销毁之前 GC 函数的上值被销毁?我认为不是(因为这可能会导致各种问题),但我正在寻找真正的答案,而不是我的想法。我承认 #1 不太可能成为问题,因为它会在 GC 元方法中产生许多问题。然而,这是完全不同的事情:
local some_string = "string" function mt:__gc() print(some_string) end
这看起来像#1,但事实并非如此。为什么?因为它访问一个全局变量。即,
print
。函数与存储的任何值之间没有直接关联
print
(与案例 1 不同,其中some_string
显然是函数的上值)。因此,print
在 Lua 状态关闭期间调用函数之前可能会被收集。
问题是:在 Lua 状态关闭期间,垃圾收集元方法是否可以安全地使用全局表中的任何内容(忽略对全局表的故意破坏的可能性)?print = nil
或者,作为一般规则,他们是否应该始终明确地将他们接触到的任何函数或数据设为本地?这足以避免问题吗?