在多值迭代期间,如果我们用完了值,则在当前版本的 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 的回复所指出的,您的代码实际上在 Perl 6.c 中引发了错误。
错误发生在第二次迭代时5, 6
,输入数组中只剩下一个,它不能映射到签名$a, $b, $c, $d
,因为该签名中的所有四个参数都是必需的。
有多种方法可以使其工作:
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
for @arr -> $a, $b = 'default-B', $c = 'default-C', $d = 'default-D' {
say ($a, $b, $c, $d);
}
这是@choroba 已经建议的。它本质上是使参数可选的另一种方式,但现在使用自定义值而不是Mu
在没有参数传递给它们的情况下。
输出:
(1 2 3 4)
(5 6 default-C default-D)
.rotor
用于处理分区。使用for
具有多参数签名的块并不是一次迭代 n 个值列表的唯一方法。该.rotor
方法以更实用的风格提供相同的功能。默认情况下,它会在最后跳过部分迭代,因此您需要为其提供:partial
包含该迭代的选项:
for @arr.rotor(4, :partial) -> @slice {
say @slice;
}
对于每次迭代,@slice
变成一个包含 4 个元素的列表,除了最后一次迭代可以有更少的元素。(你可以检查@slice.elems
循环体内部,看看你有多少。)
输出:
(1 2 3 4)
(5 6)
在我刚刚安装的 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
在到处添加分号后,我得到了
1
2
3
4
Too few positionals passed; expected 4 arguments but got 2
in block <unit> at /home/choroba/1.p6 line 2
如果您不想收到错误,可以提供默认值:
for @arr -> $a,
$b = 'Missing b',
$c = 'Missing c',
$d = 'Missing d' {
作为smls注释,您还可以将变量设为可选:
for @arr -> $a, $b?, $c?, $d? {
这与使用$var = Mu
.