【发布时间】:2020-10-08 11:35:34
【问题描述】:
我时不时地发现自己需要编写带有两个或三个分支的条件:至少一个用于定义所有两个或多个变量时,一个用于定义任何或没有定义的变量。有时最后一个分支需要是两个独立的分支。有什么短小精悍的写法?
【问题讨论】:
标签: null conditional-statements undefined raku
我时不时地发现自己需要编写带有两个或三个分支的条件:至少一个用于定义所有两个或多个变量时,一个用于定义任何或没有定义的变量。有时最后一个分支需要是两个独立的分支。有什么短小精悍的写法?
【问题讨论】:
标签: null conditional-statements undefined raku
with、without 和 orwith 是与 if、unless 和 elsif 类似的条件句,除了它们检查参数的定义性而不是真实性。与这些结合使用时,连接会成为线程,因此可以像这样编写这样的条件:
my Str $foo = '' if 2.rand.floor;
my Str $bar = '' if 2.rand.floor;
with $foo & $bar {
say 'yes';
} orwith $foo | $bar {
say 'maybe';
} else {
say 'no';
}
或者对于任意数量的变量:
my Str @strings = do 2.rand.floor ?? '' !! Nil for ^3;
with all @strings {
say 'yes';
} orwith any @strings {
say 'maybe';
} else {
say 'no';
}
【讨论】:
:_。我会编辑它。
with 等都很棒,我可能会写一个链接的 with 语句,特别是如果特定变量组合的匹配是临时的,或者我认为考虑到代码的预期演变可能会变得如此。
但考虑到你的字面问题,以及你在回答中的场景,我更有可能选择given/when:
my ($foo, $bar, $baz) = (Mu, 42).pick xx Inf;
given $foo, $bar, $baz {
when .all.defined { say 'yes' }
when .any.defined { say 'maybe' }
default { say 'no' }
}
【讨论】:
when / default 有什么意义,如果你真的是说if / elsif / else ?
default 是可选的外部异常处理程序)。 ➋ 没有$_ ~~ 的when 很聪明。直到它出现才重要,但when 确实如此,它确实如此。 ➌ when 支持 proceed / succeed(语句修饰符 when 也是)。同样,这无关紧要,直到它发生,但if 没有,句号。 ➍ 每次我重构一个 set topic / if / elsif / else 链以适应 ➋ 或 ➌ 我都想到了 ➊ 和著名的 yagni 不太知名的恼人的同卵双胞胎(你 是会需要它)。 ➎ 如果速度很重要,我会使用if...
您可以创建一个组合值并将签名用作when 条件。
(:(…) 是签名文字的语法。)
given ($foo,$bar,$baz) {
when :( Any:D, Any:D, Any:D ) { 'all defined' }
when :( Any:D, Any:D, Any:U ) { '$baz undefined' }
when :( Any:D, Any:_, Any:D ) { '$bar not checked' }
default { … }
}
您可以创建词法常量以使其更短。
my constant D = Any:D; # defined
my constant U = Any:U; # undefined
my constant _ = Any:_; # either
given ($foo,$bar,$baz) {
when :(D,D,D) { 'all defined' }
when :(D,D,U) { '$baz undefined' }
when :(D,_,D) { '$bar not checked' }
default { … }
}
或者如果你想让它更直观:
my constant term:<▣> = Any:D; # defined
my constant term:<□> = Any:U; # undefined
my constant term:<▨> = Any:_; # either
given ($foo,$bar,$baz) {
when :(▣,▣,▣) { 'all defined' }
when :(▣,▣,□) { '$baz undefined' }
when :(▣,▨,▣) { '$bar not checked' }
default { … }
}
您可以创建一个子例程,让 Signature 改为使用。
## something like this should work
## but something is weird with the returns constraint
#sub prefix:<d> ( $_ ) {
# my constant %lookup = (
# '▣' => Parameter.new( type => Any:D ),
# '□' => Parameter.new( type => Any:U ),
# '▨' => Parameter.new( type => Any:_ ),
# );
# Signature.new: params => %lookup{.comb}
#}
sub prefix:<d> ( $_ ) {
my constant %lookup = (
'▣' => 'Any:D',
'□' => 'Any:U',
'▨' => 'Any:_',
);
use MONKEY-SEE-NO-EVAL;
EVAL ":(%lookup{.comb}.join(","))"
}
given ($foo,$bar,$baz) {
when d'▣▣▣' { 'all defined' }
when d'▣▣□' { '$baz undefined' }
when d'▣▨▣' { '$bar not checked' }
default { … }
}
【讨论】: