简体   繁体   English

在 Perl 6 中,我可以使用数组作为哈希键吗?

[英]In Perl 6, can I use an Array as a Hash key?

In the Hash documentation, the section on Object keys seems to imply that you can use any type as a Hash key as long as you indicate but I am having trouble when trying to use an array as the key:在哈希文档中, Object keys部分似乎暗示您可以使用任何类型作为哈希键,只要您指出,但在尝试使用数组作为键时我遇到了问题:

> my %h{Array};
{}
> %h{[1,2]} = [3,4];
Type check failed in binding to parameter 'key'; expected Array but got Int (1)
in block <unit> at <unknown file> line 1

Is it possible to do this?是否有可能做到这一点?

The [1,2] inside the %h{[1,2]} = [3,4] is interpreted as a slice.[1,2]%h{[1,2]} = [3,4]被解释为一个切片。 So it tries to assign %h{1} and %{2} .所以它尝试分配%h{1}%{2} And since the key must be an Array , that does not typecheck well.而且由于键必须是Array ,因此类型检查不好。 Which is what the error message is telling you.这就是错误消息告诉您的内容。

If you itemize the array, it "does" work:如果您逐项列出数组,它“确实”起作用:

my %h{Array};
%h{ $[1,2] } = [3,4];
say %h.perl;  # (my Any %{Array} = ([1, 2]) => $[3, 4])

However, that probably does not get what you want, because:但是,这可能不会得到您想要的结果,因为:

say %h{ $[1,2] };  # (Any)

That's because object hashes use the value of the .WHICH method as the key in the underlying array.这是因为对象哈希使用.WHICH方法的值作为底层数组中的键。

say [1,2].WHICH; say [1,2].WHICH;
# Array|140324137953800
# Array|140324137962312

Note that the .WHICH values for those seemingly identical arrays are different.请注意,那些看似相同的数组的.WHICH值是不同的。 That's because Array s are mutable.那是因为Array是可变的。 As List s can be, so that's not really going to work.因为List可以,所以这不会真正起作用。

So what are you trying to achieve?那么你想达到什么目的? If the order of the values in the array is not important, you can probably use Set s as keys:如果数组中值的顺序不重要,您可以使用Set s 作为键:

say [1,2].Set.WHICH; say [1,2].Set.WHICH
# Set|AEA2F4CA275C3FE01D5709F416F895F283302FA2
# Set|AEA2F4CA275C3FE01D5709F416F895F283302FA2

Note that these two .WHICH es are the same.请注意,这两个.WHICH是相同的。 So you could maybe write this as:所以你可以把它写成:

my %h{Set};
dd %h{ (1,2).Set } = (3,4); # $(3, 4)
dd %h; # (my Any %{Set} = ((2,1).Set) => $(3, 4))

Hope this clarifies things.希望这能澄清事情。 More info at: https://docs.raku.org/routine/WHICH更多信息请访问: https : //docs.raku.org/routine/WHICH

If you are really only interested in use of an Object Hash for some reason, refer to Liz's answer here and especially the answers to, and comments on, a similar earlier question .如果出于某种原因您真的只对使用对象哈希感兴趣,请参阅 Liz 的回答,尤其是对之前类似问题的回答和评论。

The (final 1 ) focus of this answer is a simple way to use an Array like [1,'abc',[3/4,Mu,["more",5e6],9.9],"It's {<sunny rainy>.pick} today"] as a regular string hash key.答案的(最终1)焦点是使用一个简单的方法Array[1,'abc',[3/4,Mu,["more",5e6],9.9],"It's {<sunny rainy>.pick} today"]作为常规字符串哈希键。

The basic principle is use of .perl to approximate an immutable "value type" array until such time as there is a canonical immutable Positional type with a more robust value type .WHICH .基本原理是使用.perl来近似一个不可变的“值类型”数组,直到出现具有更健壮值类型.WHICH的规范不可变Positional类型。

A simple way to use an array as a hash key使用数组作为散列键的简单方法

my %hash;
%hash{ [1,2,3].perl } = 'foo';
say %hash{ [1,2,3].perl }; # displays 'foo'

.perl converts its argument to a string of Perl 6 code that's a literal version of that argument. .perl将其参数转换为 Perl 6 代码字符串,该字符串是该参数的文字版本。

say [1,2,3].perl;    # displays '[1, 2, 3]'

Note how spaces have been added but that doesn't matter.请注意如何添加空格,但这并不重要。

This isn't a perfect solution.这不是一个完美的解决方案。 You'll obviously get broken results if you mutate the array between key accesses.如果您在键访问之间改变数组,您显然会得到破坏的结果。 Less obviously you'll get broken results corresponding to any limitations or bugs in .perl :不太明显的是,您会得到与.perl任何限制或错误相对应的损坏结果:

say [my %foo{Array},42].perl; # displays '[(my Any %{Array}), 42]'

1 This is, hopefully, the end of my final final answer to your question. 1希望这是我对您问题的最终回答的结束。 See my earlier 10th (!!) version of this answer for discussion of the alternative of using prefix ~ to achieve a more limited but similar effect and/or to try make some sense of my exchange with Liz in the comments below.有关使用前缀~实现更有限但类似的效果和/或尝试在下面的评论中了解我与 Liz 的交流的替代方法的讨论,请参阅此答案的早期第 10 (!!) 版本

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM