perl – For Loop和Lexically Scoped变量

前端之家收集整理的这篇文章主要介绍了perl – For Loop和Lexically Scoped变量前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
版本#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循环有它自己的lexically范围版本的$count!.我只是花了两个小时试图追踪这个错误.

版本#3

use warnings;
use strict;

for $count (1..8) {
    print "Count = $count\n";
    last if ($count == 6);
}

print "That's all folks!\n";

这给了我错误全局符号“$count”需要在第5行显式包名.但是,我认为$count在for块中自动被词法限定.似乎只有在我已经在其他地方声明了这个变量的词法范围版本时才会发生这种情况.

这种行为的原因是什么?是的,我知道Conway的命令,你应该总是使用我的for循环变量,但问题是为什么Perl解释器是这样设计的.

解决方法

在Perl中,循环中对变量的赋值始终本地化为循环,循环变量始终是循环值的别名(意味着您可以通过修改循环变量来更改原始元素).包变量(我们的)和词汇变量(我的)都是如此.

这种行为最接近于Perl对包变量的动态范围(使用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
}

猜你在找的Perl相关文章