1

我有 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
4

2 回答 2

2

检查rawequal()功能。它将比较实例而不调用元方法。

于 2018-02-03T10:33:35.690 回答
2

无需在元方法内部测试相等性,__eq因为 Lua 仅在__eq用户数据指针不同时才调用元方法。

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

手册说(强调):

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

于 2018-02-03T10:53:55.010 回答