gpt4 book ai didi

raku - 使用 `eqv` 进行对象哈希查找

转载 作者:行者123 更新时间:2023-12-04 23:07:29 25 4
gpt4 key购买 nike

有没有一种方法可以在使用对象键时使用 eqv 查找哈希值,而无需循环遍历键值对?

通过在声明中指定键的类型,可以在散列中使用对象键:

class Foo { has $.bar };
my Foo $a .= new(:bar(1));
my %h{Foo} = $a => 'A', Foo.new(:bar(2)) => 'B';

但是,键查找使用身份运算符 === ,只有当它是同一个对象而不是等效对象时才会返回值:

my Foo $a-prime .= new(:bar(1));
say $a eqv $a-prime; # True
say $a === $a-prime; # False
say %h{$a}; # A
say %h{$a-prime}; # (Any)

最佳答案

查看 documentation for "===" ,最后一行显示该运算符基于 .WHICH 并且“...所有值类型都必须覆盖方法 WHICH。” 这就是为什么如果您创建两个单独的具有相同字符串值的项,"===" 返回 True

my $a = "Hello World";
my $b = join " ", "Hello", "World";

say $a === $b; # True even though different items - because same value
say $a.WHICH ; # "Str|Hello World"
say $b.WHICH ; # (same as above) which is why "===" returns True

因此,与其创建自己的容器类型或为 subscripts 使用一些 Hook ,不如,您可以改为复制“值类型”的方式 - 即屠夫(某种程度上)身份的想法。上面显示的字符串的 .WHICH 方法只返回类型名称和用 '|' 连接的内容。为什么不做同样的事情;

class Foo {
has $.bar;
multi method WHICH(Foo:D:) { "Foo|" ~ $!bar.Str }
}

my Foo $a .= new(:bar(1));
my %h{Foo} = $a => 'A', Foo.new(:bar(2)) => 'B';

my Foo $a-prime .= new(:bar(1));
say $a eqv $a-prime; # True
say $a === $a-prime; # True
say %h{$a}; # A
say %h{$a-prime}; # A

当然,这是一个很小的代价——这个类的实例的身份概念,好吧——可以说很有趣。有什么影响?立即想到的唯一一件事是,如果您打算使用某种对象持久性框架,它会将现在看起来相同的不同实例压缩成一个(也许)。

具有相同属性数据的不同对象将无法区分 - 这就是为什么我在发布此答案之前犹豫不决的原因。 OTOH,它是你的类(class),它是你的应用程序,所以根据大小/重要性等,这可能是一个很好的方法。

关于raku - 使用 `eqv` 进行对象哈希查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35775600/

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