2010-12-06 68 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語言。