Perl支持四個主循環類型:
while
for
until
foreach
在每一種情況下,繼續執行循環,直到表達計算值發生變化。
while循環有三種形式:
while EXPRLABEL while (EXPR) BLOCKLABEL while (EXPR) BLOCK continue BLOCK
在第一種形式,表達的是首先計算,然後它適用的聲明被求值。例如,以下行增加了$linecount的值和我們將繼續從一個給定的文件中讀取行:
例如,以下行增加了$linecount的值和我們將繼續從一個給定的文件中讀取行:
$linecount++ while ();
要創建一個循環,先執行語句,然後測試一個表達式,你需要結合起來,而前麵執行{}語句。例如:
do { $calc += ($fact*$ivalue); } while $calc <100;
在這種情況下,首先執行的代碼塊,條件表達式隻在每次循環結束時計算。
第二個while循環的形式反複執行代碼塊由於條件表達式的結果是真的(true)。例如,您可以重寫前麵的例子:
while($calc < 100) { $calc += ($fact*$ivalue); }
主塊主要用於為每個迭代執行一個給定的語句(或語句)後continue塊立即執行,不論怎樣終止當前迭代方法。這是某種相當於循環:
{ my $i = 0; while ($i <100) { ... } continue { $i++; } } This is equivalent to for (my $i = 0; $i < 100; $i++) { ... }
循環基本上是一個while循環重新計算原有的條件表達式使用一個額外的表達。基本格式是:
LABEL for (EXPR; EXPR; EXPR) BLOCK
第一個expr是初始化 - 變量值在循環開始之前迭代。第二是要作為一個測試循環的每次迭代執行的表達。第三個表達式為每個迭代執行,應該是一個循環變量修飾符。
因此,你可以寫一個循環來遍曆類似下麵100次:
for ($i=0;$i<100;$i++) { ... }
可以放入多個變量的表達式,使用標準的列表操作符(逗號):
for ($i=0, $j=0;$i<100;$i++,$j++)
你可以創建一個類似這樣的無限循環:
for(;;) { ... }
while循環相反的是,until循環僅在表達式返回假,計算條件表達式並重申過的循環。一旦表達式返回true,循環結束。
在一個do.until循環的案例下,條件表達式隻計算在代碼塊的結束。until(表達式)塊循環,在計算表達式之前塊執行。使用until循環,你可以重寫前麵的例子:
do { $calc += ($fact*$ivalue); } until $calc >= 100; This is equivalent to do { $calc += ($fact*$ivalue); } while $calc <100;
最後的循環類型是foreach循環中,其中有一個類似這樣的格式:
LABEL foreach VAR (LIST) BLOCK LABEL foreach VAR (LIST) BLOCK continue BLOCK
使用for循環,你可以遍曆使用列表:
for ($index=0;$index<@months;$index++) { print "$months[$index]\n"; }
這是混亂的,因為你手動選擇從數組的單個元素和使用一個額外的變量$index提取信息。使用foreach循環,可以簡化這一過程:
foreach (@months) { print "$_\n"; }
甚至可以被用來foreach循環遍曆哈希,為您提供返回值或從列表的哈希鍵列表:
foreach $key (keys %monthstonum) { print "Month $monthstonum{$key} is $key\n"; }
標簽可應用於任何塊,但它們使的在循環最有意義的。由您給定循環名稱,使閉環控製關鍵字指定操作,應適用於這樣循環。標記循環的格式是:
LABEL: loop (EXPR) BLOCK ...
例如,標簽循環:
ITERATE: for (my $i=1; $i<100; $i++) { print "Count: $i\n"; }
有三個循環控製關鍵字: next, last, and redo.
next 關鍵字跳過餘下的代碼塊,強製循環進行循環中的下一個值。例如:
while (<DATA>) { next if /^#/; }
上麵的代碼將跳過文件中的行,如果他們與一個hash符號開始。如果有一個continue塊,它執行之前繼續執行下一輪循環。
last關鍵字完全結束循環,跳過代碼塊中的剩餘的語句,以及循環丟棄。因此,最後的關鍵字與C和Shellscript break關鍵字相同。例如:
while () { last if ($found); }
將退出循環,如果發現$found的值是真的(true),該文件的末尾是否實際上已達到或冇有。不執行continue塊。
redo關鍵字重新執行不重新計算循環的條件語句的代碼塊。這將跳過餘下的代碼塊和continue塊之前重新執行主代碼塊。例如,下麵的代碼會從文件中讀取下一行,如果當前行以反斜杠終止:
while(<DATA>) { if (s#\\$#) { $_ .= <DATA>; redo; } }
下麵是一個例子展示如何在內部和外部的循環使用標簽:
OUTER: while(<DATA>) { chomp; @linearray=split; foreach $word (@linearray) { next OUTER if ($word =~ /next/i) } }
有三種基本形式:goto LABEL, goto EXPR 和 goto &NAME,在每一種情況下,執行從當前位置到目的地。
在GOTO標簽的情況下,停止執行在當前點和恢複點指定的標簽。
goto &NAME 語句更為複雜。它允許你指定的子程序,而不是取代與當前執行的子程序調用。