将“is default”与数组哈希一起使用

fin*_*fin 9 raku

这是工作示例:

my %hash;
for 1..4 -> $i {
    %hash{$i} = Array.new without %hash{$i};
    %hash{$i}.push: $_ for ^$i;
}
say %hash; # OUTPUT: {1 => [0], 2 => [0 1], 3 => [0 1 2], 4 => [0 1 2 3]}
Run Code Online (Sandbox Code Playgroud)

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

my %hash is default(Array.new);
for 1..4 -> $i {
    %hash{$i}.push: $_ for ^$i;
}
say %hash; # OUTPUT: {}
Run Code Online (Sandbox Code Playgroud)

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

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

Run Code Online (Sandbox Code Playgroud)

Jon*_*ton 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]}
Run Code Online (Sandbox Code Playgroud)

它没有给出这可能是一个错误。

然而,由于自动激活,第一个示例可以简化为:

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]}
Run Code Online (Sandbox Code Playgroud)

is default无论如何,当对未定义的值进行数组操作时,数组会自动创建,因此这意味着在这种情况下没有用处。

  • 我认为 RakuAST 本身并没有改变什么。Traits 是作为在编译时执行的多重分派来实现的,因此当我们到达 Trait 处理程序时,我们已经得到了值,而不是 AST。我真的不明白为什么当块中已经存在“will”特征时,为什么要特殊情况“is default”,因此“will default { ... }”不需要特殊情况。 (3认同)