使用“is default”与数组的哈希

huangapple go评论58阅读模式
英文:

Using "is default" with Hash of Arrays

问题

这是一个可工作的示例:
```lang-raku
my %hash;
for 1..4 -> $i {
	%hash{$i} = Array.new without %hash{$i};
	%hash{$i}.push: $_ for ^$i;
}
say %hash; # 输出:{1 => [0], 2 => [0 1], 3 => [0 1 2], 4 => [0 1 2 3]}

但是为什么下一个类似的示例不起作用?

my %hash is default(Array.new);
for 1..4 -> $i {
	%hash{$i}.push: $_ for ^$i;
}
say %hash; # 输出:{}

这甚至更让我困惑,因为下一个示例按预期工作:

my %hash is default(42);
for 1..4 -> $i {
	%hash{$i}.=Str;
}
say %hash.raku; # 输出:{"1" => "42", "2" => "42", "3" => "42", "4" => "42"}

<details>
<summary>英文:</summary>

Here is the working example:
```lang-raku
my %hash;
for 1..4 -&gt; $i {
	%hash{$i} = Array.new without %hash{$i};
	%hash{$i}.push: $_ for ^$i;
}
say %hash; # OUTPUT: {1 =&gt; [0], 2 =&gt; [0 1], 3 =&gt; [0 1 2], 4 =&gt; [0 1 2 3]}

But why the next similar example doesn't work?

my %hash is default(Array.new);
for 1..4 -&gt; $i {
	%hash{$i}.push: $_ for ^$i;
}
say %hash; # OUTPUT: {}

This even more confuses me, because the next example works as expected:

my %hash is default(42);
for 1..4 -&gt; $i {
	%hash{$i}.=Str;
}
say %hash.raku; # OUTPUT: {&quot;1&quot; =&gt; &quot;42&quot;, &quot;2&quot; =&gt; &quot;42&quot;, &quot;3&quot; =&gt; &quot;42&quot;, &quot;4&quot; =&gt; &quot;42&quot;}

答案1

得分: 12

不清楚第二个例子的结果为空哈希对我来说并不立即明显,然而像这样使用 is default 不会按您期望的那样起作用。特质在编译时应用;因此,即使 is default(Array.new) 如果正确运行,也会在编译时创建一个单独的 Array 实例,并在全局范围内重用它。因此,我期望的输出是类似于:

1 => [0 0 1 0 1 2 0 1 2 3], 2 => [0 0 1 0 1 2 0 1 2 3], 3 => [0 0 1 0 1 2 0 1 2 3], 4 => [0 0 1 0 1 2 0 1 2 3]}

它没有提供这个结果可能是一个错误。

然而,由于自动实现,第一个例子可以简化为:

my %hash;
for 1..4 -> $i {
    %hash{$i}.push: $_ for ^$i;
}
say %hash; # {1 => [0], 2 => [0 1], 3 => [0 1 2], 4 => [0 1 2 3]}

在对未定义的值执行数组操作时,数组会自动创建,因此在这种情况下不需要使用 is default

英文:

It's not immediately clear to me why the result of the second example is an empty hash, however using is default like this is not going to work as you wish. Traits are applied at compile time; thus is default(Array.new), even if it worked correctly, would create a single Array instance at compile time, and reuse it globally. So the output I'd expect is something like:

1 =&gt; [0 0 1 0 1 2 0 1 2 3], 2 =&gt; [0 0 1 0 1 2 0 1 2 3], 3 =&gt; [0 0 1 0 1 2 0 1 2 3], 4 =&gt; [0 0 1 0 1 2 0 1 2 3]}

That it doesn't give this is probably a bug.

However, thanks to auto-vivification, the first example can be reduced to:

my %hash;
for 1..4 -&gt; $i {
    %hash{$i}.push: $_ for ^$i;
}
say %hash; # {1 =&gt; [0], 2 =&gt; [0 1], 3 =&gt; [0 1 2], 4 =&gt; [0 1 2 3]}

The array is created automatically when doing an array operation on an undefined value anyway, thus meaning there's no use for is default in this kind of situation.

huangapple
  • 本文由 发表于 2023年2月18日 18:45:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/75492789.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定