100, "b" => -6ren">
gpt4 book ai didi

ruby - Hash 的 compare_by_identity 是如何工作的?

转载 作者:太空宇宙 更新时间:2023-11-03 17:02:38 26 4
gpt4 key购买 nike

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

第一部分

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。

最佳答案

docs for compare_by_identity这么说:

Makes hsh compare its keys by their identity, i.e. it will consider exact same objects as same keys.

通常,散列键将使用 eql? 进行匹配,但 compare_by_identity 将改为使用 equal? 进行匹配(大致相当于比较 object_id*)。由于具有相同值的字符串的不同实例具有不同的 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 & 'b'.object_id(或对任何字符串调用 object_id),您将每次得到不同的值。

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

关于ruby - Hash 的 compare_by_identity 是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14305398/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com