【问题标题】:Which equality test does Ruby's Hash use when comparing keys?比较键时,Ruby 的 Hash 使用哪个相等性测试?
【发布时间】:2012-06-28 14:36:06
【问题描述】:

我有一个围绕一些对象的包装类,我想将它们用作哈希中的键。包装对象和解包装对象应该映射到同一个键。

一个简单的例子是这样的:

class A
  attr_reader :x
  def initialize(inner)
    @inner=inner
  end
  def x; @inner.x; end
  def ==(other)
    @inner.x==other.x
  end
end
a = A.new(o)  #o is just any object that allows o.x
b = A.new(o)
h = {a=>5}
p h[a] #5
p h[b] #nil, should be 5
p h[o] #nil, should be 5

我试过 ==、===、eq?并哈希所有无济于事。

【问题讨论】:

  • 如果您想将大多数方法委托给@inner,您可能需要查看SimpleDelegator
  • 感谢@Marc-AndréLafortune!今天学到了一些新东西

标签: ruby hash equals equality


【解决方案1】:

哈希使用key.eql?测试键是否相等。如果您需要使用 您自己的类的实例作为哈希中的键,建议 你定义了这两个 eql?和哈希方法。哈希方法必须 具有 a.eql?(b) 隐含 a.hash == b.hash 的性质。

所以...

class A
  attr_reader :x
  def initialize(inner)
    @inner=inner
  end
  def x; @inner.x; end
  def ==(other)
    @inner.x==other.x
  end

  def eql?(other)
    self == other
  end

  def hash
    x.hash
  end
end

【讨论】:

  • 啊,所以两者都用。现在我想起来了,使用hash 获取存储桶然后使用eql? 进行实际测试是有意义的。我认为在 Java 中也是如此
  • 但是为什么eq?的默认实现不使用==
【解决方案2】:

您必须定义eql?hash

缺少Hash 的文档,但缺少has been improved recently

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-28
    • 2013-04-18
    相关资源
    最近更新 更多