Perl打破了If语句

时间:2013-06-11 20:55:59

标签: perl if-statement

这个问题刚刚出现:我如何突破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}一样在nextwhile循环中退出循环。

我喜欢mpapec's使用标签的解决方案 - 即使我不使用标签本身。标签是我for的说明:

if

虽然它不是一种标准的编码技术,但代码的流程非常明显,以至于典型的低级Perl开发人员(我离开后必须维护此代码的开发人员)可以弄清楚代码在做什么并保持它。他们甚至可能在这个过程中学到一些东西。

7 个答案:

答案 0 :(得分:26)

您可以使用受lastnextredo约束的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" }'
对于各种XY值,

具有以下结果:

X Y   Prints
-----------------------
0 0   (nothing)
0 1   (nothing)
1 0   hello, goodbye
1 1   hello