在Perl 6中,我可以迭代一个文字序列:
.say for 0 ... 3;
Run Code Online (Sandbox Code Playgroud)
我可以绑定到标量并迭代:
my $s := 0 ... 3;
.say for $s;
Run Code Online (Sandbox Code Playgroud)
但我无法绑定到标量,将其作为参数传递,然后迭代:
my $t := 0 ... 3;
show( $t );
sub show ( $seq ) { .say for $seq }
Run Code Online (Sandbox Code Playgroud)
子例程获取Seq类型的单个元素,但它不会迭代它.
0
1
2
3
0
1
2
3
(0 1 2 3)
Run Code Online (Sandbox Code Playgroud)
在准备参数的过程中有什么东西已遍历所有内容吗?
rai*_*iph 11
虽然两者$s并$seq都标量(又名"变量"),$s而您直接绑定到一个序列值$seq绑定到一个中介标量(注意大写S)"容器",里面包含的序列.当与诸如此类的功能一起使用时,标量容器中保存的值不会自动迭代for.
更详细:
my $s := 0 ... 3;
.say for $s;
Run Code Online (Sandbox Code Playgroud)
因为my变量声明使用直接绑定运算符:=进行初始化,$s所以直接绑定到单个Seq值0 ... 3.
这意味着for语句看到一个Seq值,确定它执行Iterable角色,并展平(迭代)它.
现在考虑一下:
my $s := 0 ... 3;
my $container = $s;
.say for $container;
Run Code Online (Sandbox Code Playgroud)
因为第二个my声明使用赋值运算符=进行初始化,所以新变量$container首先绑定到一个新的Scalar容器,然后"包含"所分配的任何内容.
为了与语言范围内的Slurpy Conventions保持一致(特别是:"Scalar容器中的Iterable不计算"),for语句不会迭代Scalar容器中保存的值,因此该.say for $container行只执行一个say.
类似的情况也适用于您的原始show例程,因为默认情况下,变量参数声明是(语义上)容器.
一种选择是is raw在$seq参数中添加特征:
sub show ( $seq is raw ) { .say for $seq }
Run Code Online (Sandbox Code Playgroud)
这可以防止通常自动绑定$seq到标量容器(反过来将包含Seq值)作为调用的一部分show.
另一个选择是让$seq绑定到Scalar容器,但使用前缀$seq在show例程的主体中显式地展平(迭代)变量|:
sub show ( $seq ) { .say for |$seq }
Run Code Online (Sandbox Code Playgroud)
除了is rawraiph建议的参数特性,您还可以使用无sigil的变量作为参数,它不会引入Scalar容器:
sub show (\seq) { .say for seq }
Run Code Online (Sandbox Code Playgroud)
(您也可以将此表单用于普通变量,例如my \a = 5; say a;,但请注意它们仅是单一赋值.)
这种+形式的变体是形式,如果它是一个Iterable(如a List或Seq),则传递raw参数,但是当传递一个非可迭代的参数时,它将它提升List为一个元素的一个,这样函数体可以总是得到一个Iterable:
sub show (+seq) { .say for seq }
Run Code Online (Sandbox Code Playgroud)
(这是大多数内置列表处理例程所喜欢grep和zip使用的.)
当然,如果你更喜欢使用$引入Scalar容器的参数,你可以通过调用.list它上面的方法在迭代它之前再次"去包容" 它:
sub show ($seq) { .say for $seq.list } # explicit
sub show ($seq) { .say for @$seq } # short-hand syntax
Run Code Online (Sandbox Code Playgroud)
(更新:呃,.list实际上变成了Seq一个List,即在大的情况下它不会有内存效率Seq.使用|$seq就像你在自己的答案中已经发现的那样,没有这个问题.)
| 归档时间: |
|
| 查看次数: |
145 次 |
| 最近记录: |