gpt4 book ai didi

带有自定义类的 Ruby 设置等于基本字符串

转载 作者:行者123 更新时间:2023-12-03 09:33:08 25 4
gpt4 key购买 nike

我希望能够在给定一个字符串的情况下在我的集合中找到一个自定义类。像这样:

require 'set'

Rank = Struct.new(:name, keyword_init: true) {
def hash
name.hash
end
def eql?(other)
hash == other.hash
end
def ==(other)
hash == other.hash
end
}
one = Rank.new(name: "one")
two = Rank.new(name: "two")
set = Set[one, two]

但同时 one == "one"one.eql?("one")都是真的, set.include?("one")仍然是假的。我错过了什么?

谢谢!

最佳答案

Set建立在 Hash , 和 Hash如果出现以下情况,则认为两个对象相同:

[...] their hash value is identical and the two objects are eql? to each other.



你缺少的是 eql?不一定是可交换的。制作 Rank#eql?识别字符串不会改变方式 String#eql?作品:
one.eql?('one') #=> true
'one'.eql?(one) #=> false

因此,这取决于哪个对象是散列键,哪个是 include? 的参数。 :
Set['one'].include?(one) #=> true
Set[one].include?('one') #=> false

为了使两个对象 ab可互换的哈希键,必须满足 3 个条件:
  • a.hash == b.hash
  • a.eql?(b) == true
  • b.eql?(a) == true

  • 但不要试图修改 String#eql? – 不建议摆弄 Ruby 的核心类,并且猴子补丁可能无论如何都不起作用,因为 Ruby 通常出于性能原因直接调用 C 方法。

    事实上,两者都是 hasheql?模仿 name首先,这似乎不是一个好主意。它使对象的身份模棱两可,这可能导致非常奇怪的行为并且难以发现错误:
    h = { one => 1, 'one' => 1 }
    #=> {#<struct Rank name="one">=>1, "one"=>1}

    # vs

    h = { 'one' => 1, one => 1 }
    #=> {"one"=>1}

    关于带有自定义类的 Ruby 设置等于基本字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61905948/

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