【问题标题】:Lua metamethod __newindex: "this event happens when table is not a table"?Lua元方法__newindex:“当表不是表时发生此事件”?
【发布时间】:2016-10-08 18:58:22
【问题描述】:

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

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

但是我不明白当表不是表时元方法 __newindex 会发生。这意味着什么?我确实尝试使用nil 重新分配一个本地,但它没有用(是的,我知道重新分配表没有意义,但这将有助于它被垃圾收集)。

local v = {};

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

v = nil;

我正在使用这个online compiler 来测试它。

【问题讨论】:

  • 除了当前的答案之外,应该注意您也可以为其他值设置元表。 setmetatable 可以设置表或用户数据。 debug.setmetatable 可以设置一个元表,该元表将应用于不同数据类型的每个值。
  • 不是表是什么意思:)
  • @warspy 这意味着 Lua 上的每种类型的值都是一个对象?谢谢您的帮助!在您的评论和 smarx 的回答的帮助下,我现在明白了。这应该在答案中真正注明
  • 不,不是所有的值都是对象!一点也不。例如,如果您将元表设置为 1,则所有数字都将具有该数据类型。只有表和用户数据是对象。
  • @warspyking 我明白了,这很简单!我编译了你所说的代码......ideone.com/Nu8a1W它就像一个原型......

标签: lua


【解决方案1】:

来自您引用的页面:

您可以使用 setmetatable 替换表的元表 功能。您不能从 Lua 代码更改其他类型的元表 (除了使用调试库(§6.10));你应该使用 C API 为此。

您不能使用setmetatable 来更改不是表格的东西的元表,因此您将无法验证您的期望(当您索引到不是表格的东西时会调用__newindex 方法一张桌子)。

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

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

编辑

阅读您的编辑,您似乎希望在表被垃圾回收时调用__newindex?我想你误解了__newindex 被称为“当表不是表时”的说法。这意味着如果你做了这样的事情:

local v = 5
print(v[3]) -- indexing into something that's not a table

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

【讨论】:

  • 这个很有帮助,自从我开始学习元表以来,我一直认为无法为其他值类型设置元表,但是为什么Lua接受元方法__newindex为其他值类型?
  • Lua 非常注重嵌入用例,所以我怀疑这里的灵活性是确保当通过 C 接口嵌入 Lua 时,您可以创建类似表格的东西(支持索引)实际上不是 Lua 表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-08
  • 1970-01-01
  • 2012-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多