Lua __eq具有不同元表的表



我在这个网站上找到了以下引用 http://lua-users.org/wiki/MetamethodsTutorial:

当对两个表使用 == 运算符时,调用 __eq,引用相等性检查失败,并且两个表具有相同的__eq元方法 (!(。

现在我用Lua 5.3.5测试了它,这根本不是我观察到的:

a = {}
b = {}
m = {}
m2 = {}
setmetatable(a, m)
setmetatable(b, m2)
m.__eq = function(p1, p2) print("why"); return true end
m2.__eq = function(p1, p2) print("why2"); return true end

这是我测试的代码。

> a == b
why
true
> b == a
why2
true

看起来它与比较运算符的作用相同,它只采用左侧表并使用其元方法。

这在最近的Lua版本中是否发生了变化,还是我的测试出错了?

感谢您的帮助。

这在 Lua 5.3 中发生了变化。自述文件说它为某些元方法引入了"更灵活的规则"。比较 Lua 5.2 参考手册:

==操作。函数getequalhandler定义了 Lua 如何选择相等元方法。仅当要比较的两个值具有相同类型和所选操作的相同元方法,并且这些值是表或完整用户数据时,才会选择元方法。

function getequalhandler (op1, op2)
if type(op1) ~= type(op2) or
(type(op1) ~= "table" and type(op1) ~= "userdata") then
return nil     -- different values
end
local mm1 = metatable(op1).__eq
local mm2 = metatable(op2).__eq
if mm1 == mm2 then return mm1 else return nil end
end

"eq"事件定义如下:

function eq_event (op1, op2)
if op1 == op2 then   -- primitive equal?
return true   -- values are equal
end
-- try metamethod
local h = getequalhandler(op1, op2)
if h then
return not not h(op1, op2)
else
return false
end
end

请注意,结果始终是布尔值。

使用 Lua 5.3 参考手册:

相等(==(运算。行为类似于加法操作,只是 Lua 仅在要比较的值都是表或都是完整的用户数据并且它们不原始相等时才会尝试元方法。调用的结果始终转换为布尔值。

最新更新