简短的回答是my
将变量标记为词法范围内的私有变量,并且local
将动态范围内的变量标记为私有。
更容易理解my
,因为这会创建通常意义上的局部变量。创建了一个新变量,并且只能在封闭的词法块中访问它,该词法块通常用花括号标记。大括号规则有一些例外,例如:
foreach my $x (@foo) { print "$x\n"; }
但这只是 Perl 做你的意思。通常你会有这样的事情:
sub Foo {
my $x = shift;
print "$x\n";
}
在这种情况下,$x
是子例程私有的,其范围由花括号括起来。需要注意的是,这是对比local
, 是 a 的范围my
变量是根据文件中写入的代码定义的。这是一个编译时现象。
要了解local
,您需要考虑程序运行时的调用堆栈。当一个变量是local
,它是从该点重新定义的local
语句对堆栈上低于该语句的所有内容执行,直到将堆栈返回到包含该语句的块的调用者为止local
.
一开始这可能会令人困惑,所以请考虑以下示例。
sub foo { print "$x\n"; }
sub bar { local $x; $x = 2; foo(); }
$x = 1;
foo(); # prints '1'
bar(); # prints '2' because $x was localed in bar
foo(); # prints '1' again because local from foo is no longer in effect
When foo
被称为第一次,它看到了全球价值$x
即 1. 当bar
被称为和local $x
运行,重新定义全球$x
在堆栈上。现在,当foo
被调用自bar
,它看到新值 2$x
。到目前为止,这并不是很特别,因为如果没有调用,同样的事情也会发生local
。神奇的是,当bar
返回我们退出创建的动态范围local $x
以及之前的全球$x
回到范围内。所以对于最后的呼吁foo
, $x
is 1.
你几乎总是想使用my
,因为这为您提供了您正在寻找的局部变量。千载难逢,local
做很酷的事情真的很方便。