版本#1
use warnings;
use strict;
my $count = 4;
for $count (1..8) {
print "Count = $count\n";
last if ($count == 6);
}
if (not defined($count)) {
print "Count not defined\n";
}
else {
print "Count = $count\n";
}
这打印:
1
2
3
4
5
6
4
为什么?因为for
循环创建它自己的词法作用域版本$count
在其块内。
版本#2
use warnings;
use strict;
my $count;
for $count (1..8) {
print "Count = $count\n";
last if ($count == 6);
}
if (not defined($count)) {
print "Count not defined\n";
}
else {
print "Count = $count\n";
}
1
2
3
4
5
6
Count not defined
哎呀!我想捕捉退出价值$count
,但是for
循环有它自己的词法作用域版本$count
!.我刚刚让某人花了两个小时试图找出这个错误。
版本#3
use warnings;
use strict;
for $count (1..8) {
print "Count = $count\n";
last if ($count == 6);
}
print "That's all folks!\n";
这给了我错误Global symbol "$count" requires explicit package name at line 5.
但是,我想$count
自动在词法范围内for
堵塞。似乎只有当我已经在其他地方声明了该变量的词法作用域版本时才会发生这种情况。
这种行为的原因是什么?是的,我知道康威的指示,你应该始终使用my
为了for
循环变量,但问题是为什么 Perl 解释器要这样设计。
在 Perl 中,循环中变量的赋值始终本地化到循环,并且循环变量始终是循环值的别名(这意味着您可以通过修改循环变量来更改原始元素)。对于包变量来说都是如此(our
) 和词汇变量 (my
).
此行为最接近 Perl 包变量的动态作用域(使用local
关键字),但也有处理词法变量的特殊情况(在循环中或事先声明)。
但在任何情况下,循环结束后循环的值都不会保留在循环变量中。对于循环范围的变量,这是相当直观的,但对于范围超出循环的变量,其行为类似于本地化的值(使用local
) 在循环创建的块作用域内。
for our $val (1 .. 10) {...}
相当于:
our $val;
my @list = 1 .. 10;
my $i = 0;
while ($i < @list) {
local *val = \$list[$i++];
# loop body
}
在纯 Perl 中,不可能编写扩展的词法版本,但是如果像这样的模块Data::Alias
用来:
my $val;
my @list = 1 .. 10;
my $i = 0;
while ($i < @list) {
alias $val = $list[$i++];
# loop body
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)