【问题标题】:Meta tables in lua and_index functionlua and_index 函数中的元表
【发布时间】:2014-05-23 17:48:19
【问题描述】:
__index = function(tbl, key)    
    local a = tbl[key]    
    if a <=0 then a = 0 end    
    if a > 5 then a = 0 end   
    return a
end

书说: 虽然前面的代码看起来很无辜,并试图将表中元素的值保持在一个范围内,但这段代码会导致问题和循环引用。函数中的第一行 a = tbl[key] 实际上会触发另一个索引函数调用,然后又会调用另一个函数,依此类推。

但是 a = tbl[key] 如何在每次调用时调用另一个索引?

【问题讨论】:

  • 因为tbl[key]会触发同样的__index事件。
  • @EgorSkriptunoff :我想问的是,为什么是这条链?该索引被调用,然后它又调用另一个索引函数。为什么会这样?
  • @Simrankaur 这是因为如果一个表有一个带有__index 元方法的元表并且Lua 在表中找不到键,它会调用__index 查找。如果它实际上是一张表,则调用__index 意味着该键不存在。因此,再次调用tbl[key] 肯定会一次又一次地触发__index 元方法,并且...
  • @Simrankaur - 在 __index 处理程序内部和外部的 Lua 代码中生成索引事件没有区别。
  • @Simrankaur 不,不,请参阅我的答案的编辑。 Lua 根本不会扫描 metatable 的那个键。它仅扫描 __index 字段的元表。如果元表的__index 字段指向元表本身,它将在元表中查找键。

标签: lua


【解决方案1】:

这有点奇怪。 Lua 只有在找不到表中的字段时才会触发__index 元方法。因此,在其中使用tbl[key] 完全没有意义。除非tbl 不是表格。

无论如何,如果您想从__index 中访问表的字段,请使用rawget。这将确保不会调用任何元方法。

编辑:

让我解释一下__index 查找的工作原理:

假设该表有一个定义了__index 的元表。

如果 Lua 在表中找不到键,它会在元表中查找 __index 字段。它不寻找密钥本身。然后,如果__index 是一个表,它会在该表中查找键(不是元表,尽管通常将元表本身与其__index 字段相关联)。如果是函数,则使用两个参数调用它:table(初始表,不是元表)和key

因此,如果调用__index 元方法,您可以确定初始表没有定义该字段。因此,当您尝试再次对其进行索引时(因为第一个参数是触发索引查找的原始表),故事重新开始 -> Lua 找不到键,它调用__index 等等。

【讨论】:

  • :是的,完全同意你关于 rawget 的看法,但我对这里的链接事实感到困惑,索引是用 a=tbl[key] 在链中调用的,当它不能调用元表时在表中找到一个字段,也就是索引是表的时候,但是这里我们把索引作为一个函数,书上明确说:当索引函数被调用时,它被传递了两个参数:表和键。
  • 完美答案 :) 非常感谢 :)
猜你喜欢
  • 1970-01-01
  • 2018-10-18
  • 1970-01-01
  • 1970-01-01
  • 2015-11-05
  • 2018-04-03
  • 2020-01-02
  • 2012-05-03
  • 2012-05-12
相关资源
最近更新 更多