【问题标题】:Access to pointers inside __eq meta method?访问 __eq 元方法中的指针?
【发布时间】:2018-07-13 17:30:03
【问题描述】:

我有 Lua 对象,它们共享一个元表,该元表具有 __eq 元方法。在这个元方法中,我想在比较它们之前检查这两个对象是否是同一个对象。类似于在 java 中你会做a == b || a.compareTo(b)。但问题是通过在__eq 内部执行==,它调用__eq 并因此调用堆栈溢出。我怎样才能做到这一点?

local t1 = { x = 3 }
local t2 = { x = 3 }
local t3 = t1
print(t1 == t3) -- true, they pointer to same memory
local mt = {
    __eq = function(lhs, rhs)
        if lhs == rhs then return true end -- causes stack overflow
        return lhs.x == rhs.x
    end
}
setmetatable(t1, mt)
setmetatable(t2, mt)

-- stack overflow below
print(t1 == t2) -- this should compare 'x' variables
print(t1 == t3) -- this shouldn't need to do so, same memory location

【问题讨论】:

    标签: lua meta-method


    【解决方案1】:

    没有必要在 __eq 元方法中测试相等性,因为 Lua 仅在用户数据指针不同时才调用 __eq 元方法。

    在设置元表后立即添加print(t1 == t3) 以确认这一点。

    manual 说(强调):

    __eq: 等于 (==) 操作。行为类似于加法操作,除了 Lua 仅在被比较的值是两个表或两个完整用户数据并且它们在原始上不相等时才会尝试元方法。

    【讨论】:

    • 啊,哇,我应该给元方法更多的功劳,让它足够聪明地做到这一点。在__eq 中打印证明这是真的。感谢您的帮助。
    【解决方案2】:

    检查rawequal() 函数。它会比较实例而不调用元方法。

    【讨论】:

      猜你喜欢
      • 2011-08-14
      • 2013-08-09
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      • 2023-02-16
      • 1970-01-01
      • 1970-01-01
      • 2016-12-06
      相关资源
      最近更新 更多