访问foreach循环外的变量

时间:2014-10-22 13:19:58

标签: perl

以这种方式声明的变量的范围是什么:

foreach $variable (<FILE>){
    if($variable...){

    }
}
print "$variable \n";

是否可以在循环外使用它?

提前感谢。

2 个答案:

答案 0 :(得分:6)

首先,它似乎应该有效,因为您显然没有使用strict运行此代码,因为您没有声明$variable。而你并没有将它声明为词法变量(my $variable),因此它是一个“包变量”,并且像全局一样工作。

然而,Perl不必要地,本地化了循环变量的范围。

即使这看起来应该有效:

use strict;
use warnings;
use feature 'say';
...
my $variable; # creates a lexical variable. 

foreach $variable (<FILE>){
    if($variable...){
        ...
    }
}
say $variable; # modern form of: print "$variable \n";

Perl不必要地再次,本地化变量的范围。

通常你可以将词汇声明为循环的一部分。像这样:

foreach my $variable ( <FILE> ) { 
    ...
}

它不允许您在循环外访问该变量。但是,无论您是否在循环中指定my,只需将变量放在括号之前就可以使用您可能使用的任何变量的范围。

因此,如果你想知道循环外的值是什么,它必须明确不是循环变量。

my $var;

foreach $variable ( <FILE> ) { 
    $var = $variable;
}  
say $var;

在下面的评论中,您问我有什么更好的方法来阅读文件。所以下面包含一些挑剔。

  • 到目前为止,循环文件的最佳方法是while循环。它比foreach循环具有更少的开销,而Perl语法使其易于使用。

    use English qw<$OS_ERROR>; # imports a standard readable alias for $!
    
    # 1) Use lexical file handles, not "barewords"; 2) use 3-argument open; 
    # 3) always open or die. 
    open( my $handle, '<', 'foo.txt' ) 
        or die "Could not open file: $OS_ERROR!"
        ;
    while ( my $line = <$handle> ) {
        ... 
    }
    close $handle;
    

答案 1 :(得分:3)

是的,有可能,但要注意变量总是本地化到循环(在循环后恢复以前的值)。

来自perldoc perlsyn

  

如果变量前面带有关键字 my ,那么它是词法范围的,因此只能在循环中可见。

     

否则,变量隐含在循环本地,在退出循环时重新获得其前一个值。如果先前使用my声明了变量,则它使用该变量而不是全局变量,但它仍然定位到循环。这种隐式定位仅在foreach循环中发生。