总方法和Perl 6中Bag变量的符号

时间:2018-05-03 13:47:38

标签: set perl6 bag

我们可以使用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

问题:我过去认为SetBagSetHash等,使用% sigil更可取。我错了吗?

2 个答案:

答案 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