Perl 循环语句

Perl的for循环是一个强大的特性,就像Perl的其他部分一样,可以根据需要简洁、灵活和多功能。本文涵盖了Perl for循环的核心功能。

C样式for循环

C样式for循环遵循编程传统,需要三个参数(计数;逻辑测试;计数修改器)。它的样子是这样的

use feature qw/say/;
# print numbers 0 to 9
for (my $i = 0; $i < 10; $i++) {
    say $i;
}

让我们回顾上面的代码。首先,我们导入功能'say',它类似于print命令,但它会在打印的字符串后添加一个换行符。在循环开始之前,Perl将标量变量$i初始化为零。然后Perl将检查逻辑条件($i < 10)。如果条件为真,Perl将执行大括号{ }之间的所有代码一次。Perl还会将$i增加1,因为计数修改器条件设置为$i++。完成一次迭代后,Perl将再次检查逻辑条件。在一次迭代后,$i等于1,所以Perl将再次遍历代码。这将一直持续到$i等于10,逻辑条件返回假,此时Perl将接着处理循环下面的任何代码。上面的循环使用了增量修改器($i++),但是也可以递减。

use feature qw/say/;
# print numbers 10 to 1
for (my $i = 10; $i > 0; $i--) {
    say $i;
}

实际上,我们可以使用任何我们选择的修改器,例如,要打印仅奇数,我们可以使用Perl的加到操作符$i += 2,它是($i = $i + 2)的快捷方式。

use feature qw/say/;
# print only odd numbers 1 - 9
for (my $i = 1; $i < 10; $i += 2) {
    say $i;
}

C样式for循环可以用来访问数组中的元素。

use feature qw/say/;
my @weather_elements = ('wind', 'rain', 'snow', 'cloud', 'sunshine');
for (my $i = 0; $i < @weather_elements; $i++) {
    say $weather_elements[$i];
}

请注意,计数从零开始,因为Perl数组索引是从零开始的,数组用作逻辑条件的左侧(@weather_elements),因为在这种情况下,Perl会友好地返回数组的长度(5)。

使用数组的for循环

在Perl中,迭代数组的每个元素比使用C样式for循环更简单的方法。如果一个数组被传递给for循环,它将遍历数组的每个元素,直到到达末尾。例如,下面的循环与上面的循环相同,但是使用数组技术编写

use feature qw/say/;
my @weather_elements = ('wind', 'rain', 'snow', 'cloud', 'sunshine');
for my $weather_element (@weather_elements) {
    say $weather_element;
}

在上面的代码中,Perl遍历数组,将当前元素的值赋给$weather_element。一旦循环完成,$weather_element将超出作用域,将被垃圾回收。

我们可以进一步简化这段代码。如果参数中没有包含标量变量,Perl将使用$_作为临时变量

use feature qw/say/;
my @weather_elements = ('wind', 'rain', 'snow', 'cloud', 'sunshine');
for (@weather_elements) {
    say $_;
}

有些Perl程序员使用'foreach'循环而不是'for',尽管在Perl中'for'和'foreach'是同义词,可以互换使用。我喜欢'foreach',因为它可以明确程序员的意图。例如,下面的代码将执行与上面代码示例相同的事情

use feature qw/say/;
my @weather_elements = ('wind', 'rain', 'snow', 'cloud', 'sunshine');
foreach (@weather_elements) {
    say $_;
}

for / foreach循环也可以接受列表而不是数组

use feature qw/say/;
foreach ('wind', 'rain', 'snow', 'cloud', 'sunshine') {
    say $_;
}

使用范围的for循环

有时候,你只需要Perl“做一些n次的事情”。快速做到这一点的一种方法是用范围i..n。例如,如果我们想打印6个随机的彩票数字

use feature qw/say/;
for (1..6) {
    say int(rand(58)) + 1;
}

for循环函数:redo、next和last

Perl提供了一些函数,可以用来控制for循环的迭代。redo指示Perl重新运行当前迭代。让我们修改上面的彩票数字示例,如果生成一个不幸的数字13,就重新开始循环。

for (1..6) {
    my $number = int(rand(58)) + 1;
    redo if $number == 13;
    say $number;
}

在上面的例子中,如果生成了一个数字13,redo函数将重新启动迭代,代码永远不会到达say $number语句。

函数 next 会停止当前迭代并跳转到下一个迭代。这在我们需要对某些元素进行额外处理时非常有用。例如,如果我们正在对一组人的教育情况进行调查,只有在他们有学位的情况下询问他们就读的学校才有意义。

use feature qw/say/;
for (1..5){
        print "Please type your name and press enter: ";
        my $name = <>;
        say $name;
        print "Do you have a bachelors degree? (y/n) ";
        my $degree_flag = <>;
        say $degree_flag;
        chomp $degree_flag;
        next if $degree_flag eq 'n';
        print "Which school did you get the degree from?";
        my $school = <>;
        say $school;
        # continues ...
}

函数 last 允许当前迭代完成后再退出循环。这在进行模式匹配时经常使用,因为一旦找到匹配项,就无需检查其他可能性。

my $variable_type = '$scalar';
my @perlvariable_regexes = ('^\$', '^@', '^%');
foreach (@perlvariable_regexes ){
    if ($variable_type =~ m/$_/) {
        say "match found with $_";
        last;
    }
}

有关Perl的for循环的详细信息,请查看官方Perl文档


本文最初发布在PerlTricks.com

标签

David Farrell

David是一位职业程序员,他经常在推特博客上分享关于代码和编程艺术的内容。

浏览他们的文章

反馈

这篇文章有什么问题吗?请帮助我们通过在GitHub上提交一个issue或pull request来解决。