【问题标题】:lua __index metamethod called with different tablelua __index 元方法用不同的表调用
【发布时间】:2014-08-07 01:41:34
【问题描述】:

我正在尝试即时计算矩形的顶部、底部、右侧和左侧属性,而不是将它们保留在表格中。

Rect = {}

Rect.__index = Rect

setmetatable(Rect, {
            __index = function(tbl,key)
                if key == 'right' then
                  return tbl.x + tbl.width
                elseif key == 'top' then
                  return tbl.y
                elseif key == 'left' then
                  return tbl.x
                elseif key == 'bottom' then
                  return tbl.y + tbl.height
                end

                return rawget(tbl,key)
               end
})

function Rect.new(x, y, width, height)
    return setmetatable( { x = x, y = y, width = width, height = height }, Rect )
end

function Rect:intersectsWith(other)
    return not (other.left > self.right or other.right < self.left or other.top > self.bottom or other.bottom < self.top)
end

让我感到困惑的是:

如果

Rect.__index = Rect

服务,因此实例可以针对所有缺失的方法回退到 Rect,我的自定义 __index 实现会去哪里?我试图把它放在 Rect 元表中,因为 _index 方法可以被链接起来。

结果是 __index 被调用但表错误。它崩溃是因为 tbl.x 和 lua 无法用它执行算术运算。我的猜测是传递的表是 Rect 表本身,因为调用是链式的。

【问题讨论】:

  • 确定你的猜测是否正确应该像打印出传递的值和Rect 表一样简单(或直接测试它们是否相等)。所以你应该能够很容易地做到这一点。话虽如此,我相信你是对的。
  • @EtanReisner - 是的,Rect 已通过,我刚刚检查过。我以为实例表会通过?
  • 一个__index 元方法获取与其关联的表并传递给它。考虑到发生的情况是您未能在您的实例中找到密钥(r 说),在__index 表中查找它,未能在那里找到它,然后调用__index 元方法__index 表(在本例中为 Rect)。

标签: lua


【解决方案1】:

Lua 在调用 __index 元方法之前检查键是否在索引表中,因此 return rawget(tbl,key) 是多余的。

您真正想要的是return Rect[key],它将像__index=tbl 快捷方式一样在Rect 表中查找值。

【讨论】:

  • 是的,但请记住,这是一个 Rect 元表,而不是实例。缺少值的 Rect[key] 会导致堆栈溢出,因为会调用相同的 __index 元方法。
  • 这里的建议是您手动执行链接而不是链接__index 表。因此,将该元表附加到您的实例,然后使用该返回线进行链接。至少据我所知。
  • 哎呀,没想到。谢谢!
猜你喜欢
  • 2017-02-01
  • 2012-06-29
  • 1970-01-01
  • 2016-11-21
  • 2011-03-08
  • 2013-12-18
  • 2011-03-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多