Perl foreach 循环变量作用域

Perl foreach loop variable scope

我是 perl 的新手,在编写以下代码片段后对 perl 范围规则感到困惑:

#!/usr/bin/perl
my $i = 0;
foreach $i(5..10){
    print $i."\n";
}
print "Outside loop i = $i\n";

我希望输出如下:

5
6
7
8
9
10
Outside loop i = 10

但它给了:

5
6
7
8
9
10
Outside loop i = 0

所以变量$i的值在循环退出后并没有改变。这里发生了什么?

foreach 将变量定位到循环。

use strict;
use warnings;

my $adr;
my $i = 0;
foreach $i(5..10){
    $adr = $i;
    print "$i ($adr)\n";
}
$adr = $i;
print "Outside loop i = $i ($adr)\n";

输出

5 (SCALAR(0x9d1e1d8))
6 (SCALAR(0x9d1e1d8))
7 (SCALAR(0x9d1e1d8))
8 (SCALAR(0x9d1e1d8))
9 (SCALAR(0x9d1e1d8))
10 (SCALAR(0x9d1e1d8))
Outside loop i = 0 (SCALAR(0x9d343a0))

来自 perldoc,

The foreach loop iterates over a normal list value and sets the variable VAR to be each element of the list in turn. If the variable is preceded with the keyword my, then it is lexically scoped, and is therefore visible only within the loop. Otherwise, the variable is implicitly local to the loop and regains its former value upon exiting the loop. If the variable was previously declared with my, it uses that variable instead of the global one, but it's still localized to the loop. This implicit localization occurs only in a foreach loop.

要保留 $i 的值,您可以使用 C,例如 for 循环,

my $i = 0;
for ($i = 5; $i <= 10; $i++) { .. }

尽管它的可读性不如 perl foreach

变量$i

处的foreach作用域中重新定义
foreach $i(5..10){

所以foreach外面的变量不会改变

根据有关 foreach 循环的 perldoc 信息:here

The foreach loop iterates over a normal list value and sets the variable VAR to be each element of the list in turn. If the variable is preceded with the keyword my, then it is lexically scoped, and is therefore visible only within the loop. Otherwise, the variable is implicitly local to the loop and regains its former value upon exiting the loop. If the variable was previously declared with my, it uses that variable instead of the global one, but it's still localized to the loop. This implicit localization occurs only in a foreach loop.

如果你想在循环外保留 $i 的值那么你可以在 foreach 循环调用中省略 $i 并使用 perl 的特殊变量 $_ 下面的例子:

#!/usr/bin/perl

use strict;
use warnings;

my $i = 0;
foreach (5..10){
    print $_."\n";
    $i = $_;
}
print "Outside loop i = $i\n";

5 6个 7 8个 9 10 外循环 i = 10