我们可以使用total
方法知道Bag
中所有权重的总和。
> my $b = (1,2,1).Bag
Bag(1(2), 2)
> $b.total
3
但如果我们%
使用$
sigil而不是Bag
,我们会收到错误消息。
> my %b = (1,2,1).Bag
{1 => 2, 2 => 1}
> %b.total
No such method 'total' for invocant of type 'Hash'. Did you mean 'cotan'?
in block <unit> at <unknown file> line 1
如果在%b
之前Bag
明确转换为total
,则可行:
> %b.Bag.total
3
问题:我过去认为Set
,Bag
,SetHash
等,使用%
sigil更可取。我错了吗?
答案 0 :(得分:11)
my %b := (1,2,1).Bag;
say %b.total
将左侧(<{1}}) binds 右侧直接 绑定到左侧。在这种情况下,执行Associative
角色的值会被绑定到 :=
。
%b
将 assigns (副本)值从右侧分配到 < em>容器在左侧。
您可以在第一次绑定到Bag
后进行分配,如下所示。
在赋值之前,=
声明符会将合适的容器绑定到声明的变量。默认情况下,如果变量具有Bag
sigil,则它将是my
容器。
但是你可以指定一个变量Hash
绑定到与其sigil兼容的其他类型的容器:
%
使用此咒语,您需要使用is
,因为当遇到运算符时my %b is Bag = 1,2,1;
say %b.total
已经绑定到=
,现在您需要分配(复制)< strong>进入 %b
。
这样你就可以简单地提供一个值列表(没有明确的键或Bag
coercer / constructor),因为Bag
是根据左边容器的需要来解释的,并且Bag
选择将=
的RHS解释为其发生次数对其重要的密钥列表。
答案 1 :(得分:3)
在Perl 6中,assignment to a container can be coercive,即它将值强制转换为容器的值。见:
weights
另一方面,绑定binds the type of the container to the contained thing。
所以,答案:你仍然可以使用sigil,但正如@raiph所说,使用绑定,以便Bag或BagHash不被强制转换为简单的Hash。
my $b = (1,2,1).Bag;
say $b.^name; # Bag
my %haШ = (1,2,1).Bag;
say %haШ.^name; # Hash