首页 文章

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

提问于
浏览
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 .

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

2 回答

  • 5

    正如@choroba's reply注意到,您的代码实际上在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 ("most undefined") . 请注意,不需要将第一个参数标记为可选,因为当剩下零输入元素时 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 块并不是一次一次迭代值列表的唯一方法 . .rotor 方法以更实用的方式提供相同的功能 . 默认情况下,它会跳过末尾的部分迭代,因此您需要为其提供 :partial 选项以包含该迭代:

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

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

    (1 2 3 4)
    (5 6)
    
  • 7

    尝试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 相同 .

相关问题