Skip to content

Perl 循环

循环 (loop) 是编程中基本的控制结构 (control structure),允许重复执行一段代码块。Perl 提供了几种类型的循环来处理各种迭代需求。

强烈建议在 Perl 脚本的开头使用 use strict; 和 use warnings;。

Perl 循环类型:

循环类型描述
while 循环只要给定条件为真,就重复执行代码块。条件在每次迭代之前测试。
until 循环只要给定条件为假(即直到条件变为真),就重复执行代码块。条件在每次迭代之前测试。
for 循环(C 风格)经典的由三部分组成的循环(初始化;条件;增量/减量),用于控制迭代。常用于计数。
foreach 循环(或 for 列表迭代器)遍历列表(例如数组或列表字面量)的元素。在每次迭代中,循环变量获取当前元素的值。在这种上下文中,for 和 foreach 是同义词。
do…while 循环类似于 while 循环,但条件在每次迭代之后测试。这保证循环体至少执行一次。
do…until 循环类似于 until 循环,但条件在每次迭代之后测试。保证至少执行一次。

语法:

while (condition) {
# 要执行的代码块
}

示例:

#!/usr/bin/perl
use strict;
use warnings;
my $count = 1;
while ($count <= 5) {
print "Count is: $count\n";
$count++;
}

语法:

until (condition) {
# 要执行的代码块
}

示例:

#!/usr/bin/perl
use strict;
use warnings;
my $i = 10;
until ($i < 5) {
print "i is: $i\n";
$i--;
}

语法:

for (my $variable = initial_value; condition; step) {
# 要执行的代码块
}

示例:

#!/usr/bin/perl
use strict;
use warnings;
for (my $j = 0; $j < 3; $j++) {
print "j is: $j\n";
}

foreach(或其同义词 for)遍历值列表。循环变量是列表中每个元素的别名 (alias),因此修改它会修改原始列表中的元素(如果该列表是一个数组的话)。

语法:

foreach my $item (@list) {
# 代码块,$item 是当前元素
}
# 或者使用 'for' (行为完全相同):
for my $item (@list) {
# 代码块
}
# 如果 'my $item' 被省略,则使用 $_ 作为循环变量:
# foreach (@list) {
# print "Item: $_\n";
# }

示例:

#!/usr/bin/perl
use strict;
use warnings;
my @colors = qw(red green blue);
foreach my $color (@colors) {
print "Color: $color\n";
}
# 修改数组元素(循环变量是别名)
my @numbers = (1, 2, 3);
for my $num (@numbers) {
$num *= 2; # 修改 @numbers 中的实际元素
}
print "Doubled numbers: @numbers\n"; # Output: 2 4 6

语法:

do {
# 要执行的代码块
} while (condition);

示例:

#!/usr/bin/perl
use strict;
use warnings;
my $input;
do {
print "Enter 'quit' to exit: ";
$input = <STDIN>;
chomp $input;
print "You entered: $input\n";
} while ($input ne 'quit');

语法:

do {
# 要执行的代码块
} until (condition);

可以将一个循环放在另一个循环内部。例如,遍历一个二维结构(如网格或矩阵)。

#!/usr/bin/perl
use strict;
use warnings;
for my $row (1..3) {
for my $col ('A'..'C') {
print "Cell: $row$col ";
}
print "\n"; # 每行后换行
}

Perl 提供了用于改变循环内部控制流的语句:

控制语句描述
next跳过当前迭代的剩余部分,并立即开始循环的下一次迭代(类似于 C/Java 中的 continue)。
last立即终止循环(类似于 C/Java 中的 break)。
redo从头开始重新启动当前的循环迭代,不重新评估循环条件,也不执行 continue 块。
continue BLOCK如果存在 continue 块,它会在每次循环迭代结束时执行,紧接着在重新评估循环条件之前(适用于 while, until, C 风格的 for)。它不像 next 或 last 那样是独立的语句。

使用 next 和 last 的示例:

#!/usr/bin/perl
use strict;
use warnings;
for my $num (1..10) {
if ($num % 2 == 0) {
next; # 跳过偶数
}
if ($num > 7) {
last; # 如果数字大于 7 则退出循环
}
print "Odd number: $num\n";
}
# 输出: Odd number: 1, Odd number: 3, Odd number: 5, Odd number: 7

continue 块的示例:

#!/usr/bin/perl
use strict;
use warnings;
my $lines_processed = 0;
while (my $line = <DATA>) {
chomp $line;
next if $line =~ /^\s*$/; # 跳过空行
next if $line =~ /^#/; # 跳过注释行
print "Processing: $line\n";
# ... 处理 $line ...
}
continue {
$lines_processed++; # 每次迭代都会执行,即使调用了 'next'
}
print "Total lines (including skipped): $lines_processed\n";
__DATA__
# 这是一个注释
数据行 1
数据行 2

Perl 支持各种形式的 goto 语句(goto LABEL、goto EXPR、goto &NAME)。然而,在现代结构化编程中通常不推荐使用 goto,因为它会使代码难以阅读和维护。循环控制语句(next、last、redo)和结构良好的子程序 (subroutines) 是更受青睐的替代方案。

如果循环条件永远不会变为假(对于 while/do…while)或永远不会变为真(对于 until/do…until),循环就会变成无限循环。

# 无限 C 风格 for 循环
# for (;;) {
# print "This loop runs forever...\n";
# # 需要一个 'last' 或外部终止(Ctrl+C)
# }
# 无限 while 循环
# while (1) {
# print "So does this one...\n";
# }

无限循环必须有退出机制,可以通过基于某个内部条件的 last 语句退出,或者通过外部中断(例如 Ctrl+C)终止。