For 循环和词法作用域变量 [英] For Loop and Lexically Scoped Variables

查看:64
本文介绍了For 循环和词法作用域变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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.

Why? Because the for loop creates its own lexically scoped version of $count inside its block.

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! 的词法范围版本.我刚刚有人花了两个小时试图追踪这个错误.

Whoops! I wanted to capture the exit value of $count, but the for loop had it's own lexically scoped version of $count!. I just had someone spend two hours trying to track down this bug.

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 块内进行词法作用域.似乎只有当我已经在别处声明了这个变量的词法范围版本时才会发生这种情况.

This gives me the error Global symbol "$count" requires explicit package name at line 5. But, I thought $count was automatically lexically scoped inside the for block. It seems like that only occurs when I've already declared a lexically scoped version of this variable elsewhere.

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

What was the reason for this behavior? Yes, I know about Conway's dictate that you should always use my for the for loop variable, but the question is why was the Perl interpretor designed this way.

推荐答案

在 Perl 中,对循环中变量的赋值总是本地化到循环中,而循环变量总是被循环过的值的别名(意思是你可以通过修改循环变量来改变原始元素).对于包变量(our)和词法变量(my)都是如此.

In Perl, assignment to the variable in the loop is always localized to the loop, and the loop variable is always an alias to the looped over value (meaning you can change the original elements by modifying the loop variable). This is true both for package variables (our) and lexical variables (my).

这种行为最接近 Perl 的包变量的动态范围(使用 local 关键字),但也适用于词法变量(在循环中或事先声明).

This behavior is closest to that of Perl's dynamic scoping of package variables (with the local keyword), but is also special cased to work with lexical variables (either declared in the loop or before hand).

在任何情况下,循环结束后循环的值都不会保留在循环变量中.对于循环作用域变量,这是相当直观的,但对于作用域超出循环的变量,其行为类似于在循环创建的块作用域内局部化(使用 local)的值.

In no case though does the looped over value persist in the loop variable after the loop ends. For a loop scoped variable, this is fairly intuitive, but for variables with scope beyond the loop, the behavior is analogous to a value localized (with local) inside of a block scope created by the loop.

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 这样的模块:

In pure perl it is not possible to write the expanded lexical version, but if a module like Data::Alias is used:

my $val;
my @list = 1 .. 10;
my $i = 0;

while ($i < @list) {
   alias $val = $list[$i++];
   # loop body
}

这篇关于For 循环和词法作用域变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆