Lua元方法__newindex: “当表不是表时发生此事件”?

Lua 5.3参考手册(在这个部分中,向下滚动)说:

__newindex: 对表赋值索引table[key] = value。与索引事件一样,当表不是表或键不在表中时发生此事件。在表中查找元方法。

但我不理解元方法__newindex何时发生在表不是表的情况下。那是什么意思?我确实尝试了用‘nil’重新分配一个本地变量,但它不起作用(是的,我知道重新分配表没有意义,但这将有助于它被垃圾回收)。

local v = {};

setmetatable(v, {
    __newindex = function(t,k,v)
        print("Aaahhh...!");
    end
});

v = nil;

我使用这个[在线编译器](https://www.tutorialspoint.com/lua/try_lua.php) 进行测试。

点赞
用户94559
用户94559

从您引用的页面上:

您可以使用 setmetatable 函数替换表的元表。您不能从 Lua 代码更改其他类型的元表(除非使用调试库(第 6.10 节));您应该使用 C API。

您不能使用 setmetatable 更改不是表的元表,因此您将无法验证您期望的内容(当您索引到不是表的内容时,将调用 __newindex 方法)。

您的代码运行,因为您正在为表设置元表。 (local v = {} 创建了一个表。)

但是重新分配变量 v 以成为其他内容意味着您不再有办法访问您创建的表。如果您的最后一行是 v[5] = 'Hello',那么您将看到调用您的元方法。

编辑

阅读您的编辑后,看起来您期望在垃圾回收表时调用 __newindex?我认为您误解了“在表不是表时调用 __newindex”的说法。这意味着如果您做了这样的事情:

local v = 5
print(v[3]) -- 索引到不是表的内容

将调用 __newindex(因为在表达式 table[key] 中,这里是 v[3]table 不是表)。但是您实际上无法通过 setmetatable 方法设置 __newindex,因为该方法仅适用于表。

2016-10-08 19:06:58