如果为数组分配未定义的值,它将包含该未定义的值,如果您不想迭代未定义的值,则会使用循环复杂化:
my @bar = 1, 2, Any;
for @bar -> $baz {
put $baz;
}
Run Code Online (Sandbox Code Playgroud)
这给出了以下输出,包括对未定义值的警告:
Run Code Online (Sandbox Code Playgroud)1 2 Use of uninitialized value $baz of type Any in string context. Methods .^name, .perl, .gist, or .say can be used to stringify it to something meaningful. in block at for.p6 line 4
我知道我可以通过多种方式明确地处理这个问题,例如:
for @bar -> $baz {
next unless $baz; # Skip this iteration
put $baz;
}
for @bar.grep: *.defined { # Just iterate over the defined values
put $baz;
}
# Reassign @bar to only contain defined values
@bar.=grep(*.defined);
for @bar -> $baz {
put $baz;
}
Run Code Online (Sandbox Code Playgroud)
但是,是不是有更惯用的方法来避免@foo接收未定义的值或避免迭代未定义的值?
目前,在分配数组时,我将使用以下defined-flat函数来避免这些情况:
multi defined-flat (@array) {
return @array.grep(*.defined).flat;
}
# Return single defined element (or empty list for single undefined value)
multi defined-flat ($element) {
return $element // ();
}
Run Code Online (Sandbox Code Playgroud)
你可以用 duckmap
my @bar = 1, 2, Any;
@bar.duckmap: -> Mu:D $baz {
put $baz;
}
Run Code Online (Sandbox Code Playgroud)
duckmap -> Mu:D $baz {
put $baz;
}, @bar;
Run Code Online (Sandbox Code Playgroud)
# the “:” makes this a method call
duckmap @bar: -> Mu:D $baz {
put $baz;
}
Run Code Online (Sandbox Code Playgroud)
有时也很方便的是with语句,它既可以定义,也可以测试定义:
my @bar = 1, 2, Any;
for @bar -> $baz {
put $_ with $baz
}
Run Code Online (Sandbox Code Playgroud)
要么:
my @bar = 1, 2, Any;
for @bar {
with $_ -> $baz {
put $baz;
}
}
Run Code Online (Sandbox Code Playgroud)