在多值迭代期间,如果我们用完了值,则不会在当前版本的Rakudo中处理最后一组值.
my @arr = 1,2,3,4,5,6 for @arr -> $a,$b,$c,$d { say $a say $b say $c say $d }
结果是
1 2 3 4
,下降5和6.
那么我能以哪种方式获得被删除的元素?
解决方法
正如
@choroba’s reply所述,您的代码实际上在Perl 6.c中引发了错误.
第二次迭代时发生错误,此时输入数组只剩下5,6,无法映射到签名$a,$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; }
的?表示可选 – 即当没有参数传递给该参数时,它被设置为值Mu(“最未定义”).请注意,不需要将第一个参数标记为可选,因为当剩下零输入元素时,for循环终止并且不会尝试进入另一个迭代.
输出:
--- 1 2 3 4 --- 5 6
B)指定参数的默认值.
for @arr -> $a,$b = 'default-B',$c = 'default-C',$d = 'default-D' { say ($a,$d); }
这就是@choroba已经提出的建议.它本质上是另一种使参数可选的方法,但现在使用自定义值而不是Mu,以防没有传递参数.
输出:
(1 2 3 4) (5 6 default-C default-D)
C)使用.rotor处理分区.
使用具有多参数签名的for块不是一次一次迭代值列表的唯一方法. .rotor方法以更实用的方式提供相同的功能.默认情况下,它会跳过末尾的部分迭代,因此您需要为其提供:partial选项以包含该迭代:
for @arr.rotor(4,:partial) -> @slice { say @slice; }
对于每次迭代,@ slice变成一个包含4个元素的List,除了最后一次迭代,它可以有更少的元素..(你可以检查循环体内的@ slice.elems以查看你得到了多少.)
输出:
(1 2 3 4) (5 6)