【问题标题】:How do I break out of a loop in Perl?如何在 Perl 中跳出循环?
【发布时间】:2010-09-23 03:00:09
【问题描述】:

我正在尝试在 for 循环中使用 break 语句,但由于我也在我的 Perl 代码中使用严格的 subs,所以我收到一条错误消息:

不允许使用裸词“break” ./final.pl 中使用的“严格潜艇” 第 154 行。

是否有解决方法(除了禁用严格的 subs)?

我的代码格式如下:

for my $entry (@array){
    if ($string eq "text"){
         break;
    }
}

【问题讨论】:

  • 如果你没有开启“strict subs”,当它找不到名为“break”的sub时,你会得到一个运行时错误。

标签: perl loops break strict


【解决方案1】:

哦,我找到了。你使用last 而不是break

for my $entry (@array){
    if ($string eq "text"){
         last;
    }
}

【讨论】:

  • 虽然这只是语义上的差异,除了与“下一个”命令的文本一致性之外没有其他意义。
  • 更不用说 'break' 是 >5.010 中的实验性关键字,对吧?所以你可能会得到一个非法的外部给定块错误,而不是你应该使用它。唯一可行的方法是,如果您在给定块内使用 while 循环,然后中断,这在理论上会按照您想要的方式工作,如果(并且仅当)给定块中只有 while 循环,并且假设您只是在给定一些标量变量的情况下喂食...但是为什么所有这些工作只是为了使用中断,这是(非常)糟糕的形式,更不用说(废话!)只是说,它的“可能”不是一个好想法而不是您可能认为的那样
  • 由于某种原因,我完全无法记住这个关键字'last'。总是以谷歌搜索'perl break loop' :(
  • 此外,while() 循环的工作方式相同。 my @array = ("_", "apple", "orange"); my $thing; while ($thing = shift @array){ last if $thing =~ /[A-Za-z]/; } print($thing); # "apple"
【解决方案2】:

其他数据(如果您有更多问题):

FOO: {
       for my $i ( @listone ){
          for my $j ( @listtwo ){
                 if ( cond( $i,$j ) ){

                    last FOO;  # --->
                                   # |
                 }                 # |
          }                        # |
       }                           # |
 } # <-------------------------------

【讨论】:

  • FOO 之后实际上不需要大括号:
  • 如果您在 for my $i 循环之后还有其他代码也想跳过,您可以这样做。外部的 {} 是一个裸块,它本身就是一种有趣的循环,可以是 last/redo/next'd。
【解决方案3】:

last 可以在这里工作:

for my $entry (@array){
    if ($string eq "text"){
         last;
    }
}

如果您有嵌套循环,则last 将从最内层循环退出。在这种情况下使用标签:

LBL_SCORE: {
    for my $entry1 (@array1) {
        for my $entry2 (@array2) {
            if ($entry1 eq $entry2) { # Or any condition
                last LBL_SCORE;
            }
        }
    }
 }

给定一个last 语句将使编译器从两个循环中出来。在任意数量的循环中都可以这样做,并且标签可以在任何地方固定。

【讨论】:

    【解决方案4】:

    在大型迭代中,我喜欢使用中断。只需按 Ctrl + C 即可退出:

    my $exitflag = 0;
    $SIG{INT} = sub { $exitflag=1 };
    
    while(!$exitflag) {
        # Do your stuff
    }
    

    【讨论】:

    • 确实非常有用的建议。 +1
    • @PeterMortensen - 这在 Windows 中运行良好,对于 Windows,唯一要记住的可能是在打印到 STDOUT '$|=1;` 时打开自动刷新;`
    【解决方案5】:

    对于带有 隐式循环的 Perl 单行代码(使用-n-p 命令行选项),使用lastlast LINE 来跳出遍历输入的循环记录。例如,这些简单的示例都打印输入的前 2 行:

    echo 1 2 3 4 | xargs -n1 | perl -ne 'last if $. == 3; print;'
    echo 1 2 3 4 | xargs -n1 | perl -ne 'last LINE if $. == 3; print;'
    echo 1 2 3 4 | xargs -n1 | perl -pe 'last if $. == 3;'
    echo 1 2 3 4 | xargs -n1 | perl -pe 'last LINE if $. == 3;'
    

    全部打印:

    1
    2
    

    perl 单行程序使用这些命令行标志:
    -e:告诉 Perl 查找内联代码,而不是在文件中。
    -n:循环输入一行一次,默认将其分配给$_
    -p :与-n 相同,在每次循环迭代输入后添加print

    另请参阅:

    last docs
    last, next, redo, continue - an illustrated example
    perlrun: command line switches docs


    更多关于 Perl 单行代码中 last 的示例:

    Break one liner command line script after first match
    Print the first N lines of a huge file

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-14
      • 1970-01-01
      • 2013-01-13
      • 1970-01-01
      • 2020-08-08
      • 1970-01-01
      • 2015-04-10
      • 1970-01-01
      相关资源
      最近更新 更多