Lua __eq on tables with different metatables
我在此站点上找到了以下报价http://lua-users.org/wiki/MetamethodsTutorial:
__eq is called when the == operator is used on two tables, the reference equality check failed, and both tables have the same __eq metamethod (!).
现在我用Lua 5.3.5对其进行了测试,而这根本不是我观察到的:
1 2 3 4 5 6 7 8 | 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 |
这是我测试过的代码。
1 2 3 4 5 6 | > a == b why true > b == a why2 true |
它看起来与比较运算符具有相同的功能,在比较运算符中,它仅取左表并使用其元方法。
是在最近的Lua版本中进行了此更改,还是我的测试出错了?
感谢您的帮助。
在Lua 5.3中发生了变化。自述文件说,它引入了"一些元方法更灵活的规则"。比较Lua 5.2参考手册:
the
== operation. The functiongetequalhandler defines how Lua chooses a metamethod for equality. A metamethod is selected only when both values being compared have the same type and the same metamethod for the selected operation, and the values are either tables or full userdata.
1
2
3
4
5
6
7
8
9 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
endThe"eq" event is defined as follows:
1
2
3
4
5
6
7
8
9
10
11
12 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
endNote that the result is always a boolean.
使用Lua 5.3参考手册:
the equal (
== ) operation. Behavior similar to the addition operation, except that Lua will try a metamethod only when the values being compared are either both tables or both full userdata and they are not primitively equal. The result of the call is always converted to a boolean.