【问题标题】:Matching hashes, eql? returns true, but has_key? returns false匹配哈希,eql?返回 true,但 has_key?返回假
【发布时间】:2015-04-19 11:03:35
【问题描述】:

我正在使用 Ruby 2.2.1 并且有以下情况:

a = ... # some object
h = ... # some hash

p h.size #=> 1
p h.keys.first.hash == a.hash #=> true
p h.keys.first.eql?(a) #=> true
p h.has_key?(a) #=> false

这怎么可能?我认为哈希匹配和 eql? 返回 true 是键被视为相等的唯一条件。


编辑:这是完整的程序。但请注意,我不是在问如何解决它——我知道如何解决。 我在问为什么 Ruby 会这样!因为我很困惑为什么 Hash 的 API 合同在这种情况下毫无意义。
class A
  attr_reader :x

  def initialize(x)
    @x = x
  end

  MY_HASH = { A.new(5) => 'foo' }

  def ==(other)
    @x == other.x
  end

  alias_method :eql?, :==

  def hash
    @x
  end
end

a = A.new(5)
h = A::MY_HASH

p h.size #=> 1
p h.keys.first.hash == a.hash #=> true
p h.keys.first.eql?(a) #=> true
p h.has_key?(a) #=> false

【问题讨论】:

  • 你能发布这样行为的对象吗?

标签: ruby hashmap


【解决方案1】:

在您创建MY_HASH 时,尚未定义A 的新hash 函数,因此MY_HASH 在创建其值的索引时将使用默认函数。当您稍后定义一个新的散列函数时,它将改变对象的散列方式,但不会自动更新现有散列 MY_HASH 中的索引。

在为类A 定义新的hash 方法或运行MY_HASH.rehash 之后,您可以解决我初始化MY_HASH 的问题

p h.has_key?(a) #=> false
A::MY_HASH.rehash
p h.has_key?(a) #=> true

【讨论】:

  • 很好的解释。谢谢。
猜你喜欢
  • 2019-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-06
  • 2019-08-30
  • 2020-02-03
  • 2016-02-08
  • 2016-02-22
相关资源
最近更新 更多