从Perl 6

时间:2017-12-19 20:31:03

标签: perl6

我有一个包含3个元素的数组:

my @a = <x y z>;

然后我使用Array值制作哈希值,并将@a的内容设为其值之一:

my Array %h;
%h<a> = @a;

稍后我检索此值并将其分配给另一个数组:

my @A = %h<a>;

但我在@A得到的不是一个包含3个元素的数组,而是一个元素的数组,它本身就是一个包含3个元素的数组:

say @A;          # [[x y z]]
say @A[0].elems; # 3

因此,%h<a>push加入@A

我的代码中的错误在哪里?

UPD:这似乎解决了这个问题,但并没有提高我的理解力。 :)

my @A = @(%h<a>);
say @A; [x y z]

1 个答案:

答案 0 :(得分:5)

发生这种情况的原因是,必须将数组@a放入容器中,以便将其存储为Hash中的值。容器内的某些内容在存储到数组@A时将保留在容器中。所以,你需要的是在分配给@A时摆脱容器。你的解决方案是摆脱容器的一种方法,但这会产生一个中间List,对于大型数组而言可能会变得昂贵。

正如我所说,你需要摆脱容器。幸运的是,我们有一个语法:postfix <>

my @a = <a b c>;
my %h = a => @a;
my @b = %h<a><>;  # <-- note the <> here
dd @b;    # Array @b = ["a", "b", "c"]

如果您真的希望@b可变,这将是最有效的方法。或者,如果您希望@b只是原始@a的别名,您还可以绑定:

my @a = <a b c>;
my %h = a => @a;
my @b := %h<a>;  # <-- note the := here
dd @b;    # Array @a = ["a", "b", "c"]

请注意,dd输出现在显示@a作为名称,因为它现在与@a实际上相同:@a的任何更改现在也会显示在@b,反之亦然。如果您还没有改变它们,那也没关系。如果在您的情况下这是真的,那么这将是最有效的方式,无论是CPU还是内存方式。