如何在 Perl 6 的多值迭代过程中意识到缺失值?
How to be aware of missing values during multi-value iteration in Perl 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
,会掉落 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
相同。
如 所述,您的代码实际上在 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")。请注意,无需将 first 参数标记为可选,因为当输入元素为零时,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)
在多值迭代过程中,如果我们运行个值,最后一组值将不会在当前版本的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
。
那么我可以通过什么方式获取掉落的元素?
在我刚刚安装的 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
相同。
如
错误发生在第二次迭代时,输入数组只剩下 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")。请注意,无需将 first 参数标记为可选,因为当输入元素为零时,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)