将元素添加到循环内声明为 "state %set is SetHash[Str]" 的 SetHash 时抛出异常

Exception thrown when adding an element into a SetHash declared as "state %set is SetHash[Str]" inside a loop

在循环内将 Str 元素添加到声明为 state %set is SetHash[Str] 的 SetHash 会引发异常:

Cannot resolve caller STORE(SetHash[Str]:U: SetHash[Str]:D); none of these signatures match:

(SetHash:D: *@pairs, *%_ --> SetHash:D)

(SetHash:D: \objects, \bools, *%_ --> SetHash:D)

(QuantHash:D: |)

当在循环之前声明为 my %set is SetHash[Str] 时,相同的代码工作得很好。

根据https://docs.raku.org/type/SetHash#Creating_SetHash_objects

...

Since 6.d (2019.03 and later) it is also possible to specify the type of values you would like to allow in a SetHash.

This can either be done when calling .new:

#only allow Pairs

my $n = SetHash[Pair].new: "zero" => 0, "one" => 1, "two" => 2;

or using the masquerading syntax:

#only allow strings

my %sh is SetHash[Str] = <a b c>;

say %sh<a>; # True

say %sh<d>; # False

...

当以前一种方式 (%set = SetHash[Str].new) 声明 HashSet 时,它会按预期工作(在循环之前或循环内)。 问题出现在后者身上。

什么有效:

use v6.d;

my @list = 'aaa' .. 'ddd';

my %set is SetHash[Str];

for @list {
    %set{$_}++ if m/a.*a/;

    LAST {
        put %set.elems;
    }
}
#outputs 10

什么没有:

use v6.d;

my @list = 'aaa' .. 'ddd';

for @list {
    state %set is SetHash[Str];

    %set{$_}++ if m/a.*a/;

    LAST {
        put %set.elems;
    }
}
#outputs the exception

这是为什么?这是一个错误吗?

(在Rakudo 2019.07.1和2019.03测试结果相同)

state 声明中的 is Foo 有问题。

参见,例如 [BUG] state with % is SetHash ends up with a type object on second entry to block

我记得还必须写:

my @array is BigArray;
proto A(Int \, Int \) { @array[][] //= {*} }

而不是

proto A(Int \, Int \) { (state @array is BigArray)[][] //= {*} }

前阵子,所以我认为有比 SetHashs 更普遍的东西。