6

在多值迭代期间,如果我们用完了值,则在当前版本的 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

, 下降56.

那么我可以通过哪种方式获得被丢弃的元素?

4

2 回答 2

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;
}

意思是可选的?——即当没有参数传递给该参数时,它被设置为值Mu(“最未定义”)。请注意,无需将第一个参数标记可选,因为当输入元素为零时,for循环终止并且不会尝试进入另一个迭代。
输出:

---
1
2
3
4
---
5
6

B) 指定参数的默认值。

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)

C).rotor用于处理分区。

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

for @arr.rotor(4, :partial) -> @slice {
    say @slice;
}

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

(1 2 3 4)
(5 6)
于 2017-05-28T09:00:38.817 回答
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

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

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.

于 2017-05-28T08:34:30.363 回答