如何在Perl 6的多值迭代过程中注意缺失值?

hwd*_*ing 6 arrays for-loop rakudo perl6

在多值迭代期间,如果我们用完了值,则不会在当前版本的Rakudo中处理最后一组值.

my @arr = 1, 2, 3, 4, 5, 6
for @arr -> $a, $b, $c, $d {
  say $a
  say $b
  say $c
  say $d
}
Run Code Online (Sandbox Code Playgroud)

结果是

1
2
3
4
Run Code Online (Sandbox Code Playgroud)

,滴,56.

那么我能以哪种方式获得被删除的元素?

sml*_*mls 7

正如@ choroba的回复说明,您的代码实际上在Perl 6.c中引发了错误.

第二次迭代时发生错误,仅从5, 6输入数组中留下,无法映射到签名,$a, $b, $c, $d因为该签名中的所有四个参数都是必需的.

有多种方法可以使它工作:

A)将参数标记为可选.

for @arr -> $a, $b?, $c?, $d? {
    say "---";
    say $a;
    say $b if $b.defined;
    say $c if $c.defined;
    say $d if $d.defined;
}
Run Code Online (Sandbox Code Playgroud)

?意味着可选 - 即当没有参数传递给该参数时,它被设置为值Mu("最未定义").请注意,不需要将第一个参数标记为可选,因为当剩下零输入元素时,for循环终止并且不会尝试进入另一个迭代.
输出:

---
1
2
3
4
---
5
6
Run Code Online (Sandbox Code Playgroud)

B)指定参数的默认值.

for @arr -> $a, $b = 'default-B', $c = 'default-C', $d = 'default-D' {
    say ($a, $b, $c, $d);
}
Run Code Online (Sandbox Code Playgroud)

这就是@choroba已经提出的建议.它本质上是使参数可选的另一种方法,但现在使用自定义值而不是Mu没有传递参数的情况.
输出:

(1 2 3 4)
(5 6 default-C default-D)
Run Code Online (Sandbox Code Playgroud)

C).rotor用于处理分区.

使用for具有多参数签名的块不是一次一次迭代值列表的唯一方法.该.rotor方法以更实用的方式提供相同的功能.默认情况下,它会跳过末尾的部分迭代,因此您需要为其提供:partial包含该迭代的选项:

for @arr.rotor(4, :partial) -> @slice {
    say @slice;
}
Run Code Online (Sandbox Code Playgroud)

对于每次迭代,@slice变成一个包含4个元素的List,除了最后一次迭代,它可以有更少的元素.(你可以检查@slice.elems循环体内部以查看你得到了多少.)
输出:

(1 2 3 4)
(5 6)
Run Code Online (Sandbox Code Playgroud)


cho*_*oba 5

尝试Rakudo Star我刚刚安装:

===SORRY!=== Error while compiling /home/choroba/1.p6
Unexpected block in infix position (missing statement control word before the expression?)
at /home/choroba/1.p6:2
------> for @arr? -> $a, $b, $c, $d {
    expecting any of:
        infix
        infix stopper
Run Code Online (Sandbox Code Playgroud)

在各处添加分号之后,我得到了

1
2
3
4
Too few positionals passed; expected 4 arguments but got 2
  in block <unit> at /home/choroba/1.p6 line 2
Run Code Online (Sandbox Code Playgroud)

如果您不想收到错误,可以提供默认值:

for @arr -> $a,
            $b = 'Missing b',
            $c = 'Missing c',
            $d = 'Missing d' {
Run Code Online (Sandbox Code Playgroud)

作为smls注释,您还可以使变量可选:

for @arr -> $a, $b?, $c?, $d? {
Run Code Online (Sandbox Code Playgroud)

这将与使用相同$var = Mu.