Perl 6 可以将 % sigil 用于 Hash 之外的其他东西吗?
Can Perl 6 use the % sigil for something other than a Hash?
有关变量的 Perl 6 文档指出,%
印记可用于将 Associative role. It specifically mentions Pair, Hash, and Map. But, how would I get a Pair 转换为具有 %
?
的变量的类型
如果我使用类型约束,我会得到一个奇怪的错误:
> my Pair %pair = Pair.new( 'a', 'b' )
Type check failed in assignment to %pair; expected Pair but got Str ("b")
in block <unit> at <unknown file> line 1
如果我在没有类型约束的情况下分配,我会得到一个散列:
my %pair = Pair.new: 'a', 'b'; # Hash, not Pair
绑定作品:
my %pair := Pair.new: 'a', 'b'; # Pair
但是如果我使用类型约束,我会得到另一个奇怪的错误:
> my Pair %p2 := Pair.new: 'a', 'b';
Type check failed in binding; expected Associative[Pair] but got Pair (:a("b"))
in block <unit> at <unknown file> line 1
同样的问题出现在 Bag and Set. Do it with Map and you end up with a mutable Hash。
我认为这里存在各种问题,但也许 %
印记并不像我所相信的那样多才多艺。
您可以使用 %
标记容器来保存 does
Associative
角色的任何值。
正如您发现的那样,您必须小心声明和分配的方式。
在您的示例 my Pair %pair
中,您是说制作一个 Hash
(不是 Pair
),它可以容纳 Pair
个值(%pair.WHAT = 'Hash[Pair]'
)
试试这个:
my Pair %p2 = mykey => Pair.new: 'a', 'b';
这很好。通过限制值的类型,如果你说
,你会得到一个错误
%p2<c> = 'd';
因为您没有分配 Pair
。
正如您还发现的那样,绑定按照您认为的方式工作。
如果我们想了解您的示例发生了什么,我们需要退后几步:
变量绑定到对象。默认情况下,带符号的变量最初绑定到可分配的容器对象(Scalar
用于 $
和 &
,Array
用于 @
和 Hash
用于 %
).
如果将类型添加到变量声明中,例如
my Int %var
或等效的
my %var of Int
您对该容器可以容纳的值的类型进行了限制。
变量赋值 (=
) 尝试将右侧的值放入绑定到左侧变量的容器中,如果不满足此类型约束,则会失败。默认情况下,只有 &
个变量带有这样的约束(参见 (my &).VAR.of
与 (my %).VAR.of
)。
相比之下,重新绑定变量 (:=
) 将替换容器对象。如果要限制可以绑定的对象类型,则需要 is
if of
:
my %var is Pair;
%var := x => 1; # ok
%var := 42; # not ok
Sigilled 变量意味着默认类型约束(none 代表 $
,Callable
代表 &
,Positional
代表 @
和 Associative
对于 %
)。请注意,此默认约束会被显式约束覆盖,例如
my %var is Int;
%var := 42; # ok even though 42 is not Associative
最后,请注意 is
不仅设置类型约束,还会将变量绑定到该类型的新创建实例:
my %pair is Pair;
say %pair; # (Mu) => (Mu), ie Pair.new()
我不知道有什么方法可以只做前者。
老实说,这对我来说就像是一个错误。 %
容器存储通过粗箭头中缀构造函数构造的 Pair
没有问题:
my %pair = what => 'a pair';
尽管容器会覆盖类型,因此您得到的是 Hash
而不是 Pair
。
%pair.WHAT; #=> (Hash)
有关变量的 Perl 6 文档指出,%
印记可用于将 Associative role. It specifically mentions Pair, Hash, and Map. But, how would I get a Pair 转换为具有 %
?
如果我使用类型约束,我会得到一个奇怪的错误:
> my Pair %pair = Pair.new( 'a', 'b' )
Type check failed in assignment to %pair; expected Pair but got Str ("b")
in block <unit> at <unknown file> line 1
如果我在没有类型约束的情况下分配,我会得到一个散列:
my %pair = Pair.new: 'a', 'b'; # Hash, not Pair
绑定作品:
my %pair := Pair.new: 'a', 'b'; # Pair
但是如果我使用类型约束,我会得到另一个奇怪的错误:
> my Pair %p2 := Pair.new: 'a', 'b';
Type check failed in binding; expected Associative[Pair] but got Pair (:a("b"))
in block <unit> at <unknown file> line 1
同样的问题出现在 Bag and Set. Do it with Map and you end up with a mutable Hash。
我认为这里存在各种问题,但也许 %
印记并不像我所相信的那样多才多艺。
您可以使用 %
标记容器来保存 does
Associative
角色的任何值。
正如您发现的那样,您必须小心声明和分配的方式。
在您的示例 my Pair %pair
中,您是说制作一个 Hash
(不是 Pair
),它可以容纳 Pair
个值(%pair.WHAT = 'Hash[Pair]'
)
试试这个:
my Pair %p2 = mykey => Pair.new: 'a', 'b';
这很好。通过限制值的类型,如果你说
,你会得到一个错误%p2<c> = 'd';
因为您没有分配 Pair
。
正如您还发现的那样,绑定按照您认为的方式工作。
如果我们想了解您的示例发生了什么,我们需要退后几步:
变量绑定到对象。默认情况下,带符号的变量最初绑定到可分配的容器对象(Scalar
用于 $
和 &
,Array
用于 @
和 Hash
用于 %
).
如果将类型添加到变量声明中,例如
my Int %var
或等效的
my %var of Int
您对该容器可以容纳的值的类型进行了限制。
变量赋值 (=
) 尝试将右侧的值放入绑定到左侧变量的容器中,如果不满足此类型约束,则会失败。默认情况下,只有 &
个变量带有这样的约束(参见 (my &).VAR.of
与 (my %).VAR.of
)。
相比之下,重新绑定变量 (:=
) 将替换容器对象。如果要限制可以绑定的对象类型,则需要 is
if of
:
my %var is Pair;
%var := x => 1; # ok
%var := 42; # not ok
Sigilled 变量意味着默认类型约束(none 代表 $
,Callable
代表 &
,Positional
代表 @
和 Associative
对于 %
)。请注意,此默认约束会被显式约束覆盖,例如
my %var is Int;
%var := 42; # ok even though 42 is not Associative
最后,请注意 is
不仅设置类型约束,还会将变量绑定到该类型的新创建实例:
my %pair is Pair;
say %pair; # (Mu) => (Mu), ie Pair.new()
我不知道有什么方法可以只做前者。
老实说,这对我来说就像是一个错误。 %
容器存储通过粗箭头中缀构造函数构造的 Pair
没有问题:
my %pair = what => 'a pair';
尽管容器会覆盖类型,因此您得到的是 Hash
而不是 Pair
。
%pair.WHAT; #=> (Hash)