2010-12-06 65 views
7

根据perl手册中的lasthttp://perldoc.perl.org/functions/last.html),last不能用于突破do {}循环,但没有提及替代方案。我维护的脚本有这样的结构:替代“do”循环中的“last”

do { 
    ... 
    if (...) 
    { 
     ... 
     last; 
    } 
} while (...); 

,我敢肯定,他希望去循环的结束,但它实际上退出当前子程序,所以我需要更改的last或者如果有人可以推荐更好的方法重构整个循环。

+0

另一种方法是不使用`do {}`。 – 2013-01-09 17:07:57

回答

10

do BLOCK while (EXPR)很有趣在做的是不是一个真正的循环结构。所以,最后一个,下一个和重做不应该在那里使用。当发现这种情况时,摆脱最后一项并调整EXPR以评估错误。 另外,打开严格的,这应该给你至少在这里警告。

+2

+1:这不是一个循环。 – 2010-12-06 18:26:41

1

@ “http://perldoc.perl.org/functions/last.html”: 最后不能用于退出返回一个值,如EVAL {},{子块}或do {},并且不应该用于退出grep()或map()操作。

所以,在“而()”使用一个布尔值,并设置它,你有“最后” ......

16

裹在裸块做“循环”(这是一个循环):

{ 
    do { 
     ... 
     if (...) 
     { 
      ... 
      last; 
     } 
    } while (...); 
} 

这适用于过去和重做,但不是未来;对于那个地方,裸块在do块内:

do {{ 
    ... 
    if (...) 
    { 
     ... 
     next; 
    } 
    ... 
}} while (...); 
+0

优雅。 +1。 ... – DVK 2010-12-06 19:54:18

+3

这在[perlsyn](http://perldoc.perl.org/perlsyn.html#Statement-Modifiers)中提到过,尽管我认为如果您在裸露的区块和上次使用的标签上更清晰`声明。 – cjm 2010-12-06 20:30:30

2

从来不是Perl/Perl中的do/while循环的粉丝。 do不是一个真正的循环,这就是为什么last不会摆脱它。在我们的旧Pascal发呆,你不能退出中间的循环,因为根据圣尼古拉斯“一个入口/一个出口”Wirth根本就是错误的。因此,我们必须创建一个退出标志。在Perl中,它看起来像这样:

my $endFlag = 0; 
do { 
    ... 
    if (...) 
    { 
     ... 
     $endFlag = 1; 
    } 
} while ((...) and (not $endFlag)); 

现在,你可以看到,而帕斯卡从来没有发现。

1

为什么不使用while循环?

while (...) { 
    ... 
    if (...) { 
    last; 
    } 
} 

您可能需要改变你的逻辑稍微适应的事实,你的测试是在一开始的,而不是你的循环结束,但应该是微不足道的。

顺便说一句,如果你使用Delphi,你实际上可以跳出一个Pascal循环,并且Delphi DID会持续一段时间,直到微软提出并推出.net语言。