这个问题刚刚出现:我如何突破if
声明?我有一个很长的if语句,但有一种情况我可以在早期就突破它。
在循环中,我可以这样做:
while (something ) {
last if $some_condition;
blah, blah, blah
...
}
但是,我可以用if语句做同样的事吗?
if ( some_condition ) {
blah, blah, blah
last if $some_other_condition; # No need to continue...
blah, blah, blah
...
}
我知道我可以将if
语句放在一个块中,然后我可以突破块:
}
if ( some_condition ) {
...
last if $some_other_condition; # No need to continue...
blah, blah, blah
...
}
}
或者,我可以创建一个子程序(可能以编程方式更好):
if ( some_condition ) {
run_subroutine();
}
sub run_subroutine {
blah, blah, blah
return if $some_other_condition;
blah, blah, blah
...
}
但是有没有退出if条件?
问题出现了,因为我正在帮助某人使用他们的代码。在一个相当长的if
语句中,其中嵌入了其他几个if
语句。代码看起来像这样:
if ( $condition1 ) {
blah, blah, blah;
if ( not $condition2 ) {
blah, blah, blah;
if ( not $condition3 ) {
blah, blah, blah;
}
}
}
我认为通过这样做可以使整个事情更具可读性:
if ( $condition1 ) {
last if $condition2;
blah, blah, blah;
last if $condition3;
blah, blah, blah;
}
这表明if
语句的正常流程是标准的,但在某些条件下,if
语句提前退出 - 就像使用last
或{{1}一样在next
或while
循环中退出循环。
我喜欢mpapec's使用标签的解决方案 - 即使我不使用标签本身。标签是我for
的说明:
if
虽然它不是一种标准的编码技术,但代码的流程非常明显,以至于典型的低级Perl开发人员(我离开后必须维护此代码的开发人员)可以弄清楚代码在做什么并保持它。他们甚至可能在这个过程中学到一些东西。
答案 0 :(得分:26)
您可以使用受last
,next
和redo
约束的basic block,因此可能会中断。
if ($condition) {EXIT_IF:{
last EXIT_IF; # break from code block
print "never get's executed\n";
}}
EXIT_IF: {
if ($condition) {
last EXIT_IF; # break from code block
print "never get's executed\n";
}
}
答案 1 :(得分:3)
将其放入空的for()
循环中,然后在last;
之后的任何地方添加if
。有点难看,但有效。确保添加注释来解释这个技巧。
for (;;) {
if (condition) {
#code
last if another_condition;
}
last;
}
使用goto
并在循环后为该goto标记一个语句。永远该死的。
if
内的额外阻止(例如if () {{ code }}
)。可能很难为新手阅读,但如果附有评论就可以。
您自己的解决方案:阻止if
。
您自己的解决方案:返回子程序。
坦率地说,除非调用子事项的成本是明智的,否则就可读性而言,这是最干净的解决方案。
答案 2 :(得分:2)
您可以将if
块的其余部分放在另一个if
语句中,如下所示:
if (some_condition) {
blah, blah, blah
if (!$some_other_condition) {
blah, blah, blah
...
}
}
答案 3 :(得分:0)
另一种方法是使用匿名子程序 注意: 我不建议使用此方法,因为增加了范围的复杂性(请参阅下面的注释);这只是为了完成可能的答案。
if( $true_condition ){
(sub{
return if $true_condition;
...
})->();
}
注意:如果您希望在其余代码中使用它们,则例程中声明的任何变量必须使用our
而不是my
。
答案 4 :(得分:0)
我倾向于使用基于“我会继续吗?”的顺序if语句。变量而不是。您的
if ( $condition1 ) {
blah, blah, blah;
if ( not $condition2 ) {
blah, blah, blah;
if ( not $condition3 ) {
blah, blah, blah;
}
}
}
可以重新排列为
my $ok = $condition1;
if ($ok) {
blah, blah, blah;
$ok = not $condition2;
}
if ($ok) {
blah, blah, blah;
$ok = not $condition3;
}
if ($ok) {
blah, blah, blah;
}
答案 5 :(得分:0)
保持while
循环,以便您可以使用last
,但确保循环最多执行一次
my $loop_once = 1;
while ( $loop_once-- and some_condition ) {
blah, blah, blah
last if $some_other_condition; # No need to continue...
blah, blah, blah
...
}
答案 6 :(得分:0)
我被DVK's answer的灵感所吸引,我想出了这个至少在Perl 5.26.1上有效的变体:
for( ; some_condition ; last ) {
blah, blah, blah
last if $some_other_condition; # No need to continue...
blah, blah, blah
}
每perlsyn
,这相当于:
while (some_condition) {
blah, blah, blah
last if $some_other_condition; # No need to continue...
blah, blah, blah
} continue {
last;
}
在continue
块中,last
与在主循环中执行的效果相同。因此,循环将执行零次或一次,具体取决于some_condition
。
perl -E 'my ($cond, $other)=(X, Y);
for(;$cond;last) { say "hello"; last if $other; say "goodbye" }'
对于各种X
和Y
值,具有以下结果:
X Y Prints
-----------------------
0 0 (nothing)
0 1 (nothing)
1 0 hello, goodbye
1 1 hello