想象一个包括类似的类:
class Element
include Comparable
attr_accessor :name, :pos_x, :pos_y
def initialize(name, pos_x, pos_y)
@name = name
@pos_x = pos_x
@pos_y = pos_y
end
def <=>(other)
if (@pos_x == other.pos_x) and (@pos_y == other.pos_y)
return 0
else
return @name <=> other.name
end
end
def eql?(other)
self == other
end
end
在这种情况下hash
,您将如何实现该功能a.hash == b.hash
?一般来说,我会这样做:
def hash
@name.hash
end
但这不包括pos_x
和pos_y
。
不幸的是,在这种情况下,从数学上讲不可能定义有效的哈希函数。
设a,b为两个位置相等且名称不同的元素。根据eql?
定义,这意味着h(a) == h(b)
。由于对于任何名称值都是如此,因此哈希函数将独立于名称属性,但这与第二次检查是矛盾的。因此,此eql?
定义没有哈希函数。抱歉。:(
更新:
如toro2k所述-您的相等性定义不是可传递的。通常,如果a == b和b == c,则要求a == c。根据您的eql?
功能:
{pos_x: 1, pos_y: 1, name: 'a'} == {pos_x: 1, pos_y: 1, name: 'b'}
{pos_x: 1, pos_y: 1, name: 'b'} == {pos_x: 2, pos_y: 2, name: 'b'}
但
{pos_x: 1, pos_y: 1, name: 'a'} != {pos_x: 2, pos_y: 2, name: 'b'}
这就是您问题的根源。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句