哈希的compare_by_identity如何运作?

我首先运行下面的代码第一部分并获得所需的输出,现在只是为了解决它并做一些研究我做了第二部分。

第一部分

irb(main):001:0> h1 = { "a" => 100, "b" => 200, :c => "c" } => {"a"=>100, "b"=>200, :c=>"c"} irb(main):002:0> h1["a"] => 100 irb(main):002:0> h1[:c] => "c" 

第二部分

 irb(main):003:0> h1.compare_by_identity => {"a"=>100, "b"=>200, :c=>"c"} irb(main):004:0> h1.compare_by_identity? => true irb(main):005:0> h1["a"] => nil irb(main):006:0> h1[:c] => "c" irb(main):007:0> 

h1["a"]如何在第一部分和第二部分中给出不同的值,但在h1[:c]却不一样?

我正在使用Ruby 1.9.3。

compare_by_identity的文档说:

使hsh按其身份比较其密钥,即它将考虑与相同密钥完全相同的对象。

通常,使用eql?匹配哈希键eql? ,但compare_by_identity将使用equal?匹配它们equal? (大致相当于比较object_id s *)。 由于具有相同值的字符串的不同实例具有不同的object_id ,因此它不匹配。 但是,符号始终具有相同的object_id ,因此它会继续匹配。

 hash = { 'a' => 'str a', 'b' => 'str b', :c => 'sym c' } hash.compare_by_identity hash.keys.map(&:object_id) #=> [70179407935200, 70179407935180, 358408] ['a', 'b', :c].map(&:object_id) #=> [70179405705480, 70179405705460, 358408] hash.keys.zip(['a', 'b', :c]).map { |pair| pair.inject(:eql?) } #=> [true, true, true] hash.keys.zip(['a', 'b', :c]).map { |pair| pair.inject(:equal?) } #=> [false, false, true] a_key = hash.keys.first #=> 'a' hash['a'] #=> nil hash[a_key] #=> 'str a' hash[:c] #=> 'sym c' 

如您所见,字符串的object_id与哈希中键的object_id不匹配,但符号却与。 实际上,如果'a'.object_id运行'a'.object_id'b'.object_id (或对任何字符串调用object_id ),每次都会得到不同的值。

*这里需要注意的是,可以覆盖object_id ,但它会对比较产生影响,因为它equal? 实际上并没有使用object_id 进一步,重新定义equal? 将改变这一点,但不建议在Ruby文档中明确这样做。