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 语句更为复杂。它允许你指定的子程序,而不是取代与当前执行的子程序调用。