13

在写这个程序之前,我以为这our是一个包范围变量,my是一个文件范围变量。但是,在写完那个程序之后,我很困惑。

我的程序是,

#!/usr/bin/perl

use strict;
use warnings;

package one; 
our $val = "sat";
my $new = "hello";
print "ONE:val =>$val \n";
print "ONE:new =>$new \n\n";

package two;
print "TWO:val =>$val \n";
print "TWO:new =>$new \n";

哪个输出

ONE:val =>sat 
ONE:new =>hello 

TWO:val =>sat 
TWO:new =>hello 

那么,my和之间our有什么区别。两者是相同的还是有区别的?

4

3 回答 3

20

如你所见,两者都my具有our词法作用。

my创建一个词法范围的变量。

our创建包变量的词法范围别名。

仅仅因为你说不package改变词法范围,所以即使在看到语句之后你$val仍然是别名。$one::valpackage two

如果你没有看到一个紧密的卷曲,你还没有完成你的范围。(或 EOF 或字符串中的字符串结尾eval)。

于 2012-05-23T12:38:19.253 回答
6

将变量访问限制在声明它们的最里面的块中。如果没有块,它们是文件范围的。

相反,我们将一个简单的名称与当前包中的包变量相关联,因此它在包级别声明并链接到包名。我们试图通过让您在不添加包名称的情况下使用包变量来提供帮助。

package pack;
our $variable;    # These are the same
$pack::variable;  # These are the same

our变量类似于 C 的静态变量,但不同的是,如果使用变量的完全限定名称调用函数中使用 our 声明的变量,仍然可以在函数外部访问它。

但是最重​​要的是my是词法范围,而our是词法范围,但它们的生命即使在声明块之外也是持久的(它们的生命就像全局变量生命),因此要真正理解myour之间的区别,您必须了解词法之间的区别和 Perl 中的全局范围。

简而言之,这两种类型之间的区别是:

全局变量

任何地方的任何代码都可以更改它们的值。

词法变量

变量的生命周期以包含它们的代码块的结尾而结束,之后它们的值被垃圾收集。这类变量只能在声明它们的块内访问。


回答你具体的示例问题: 尝试将第二个包声明(包二)移动到另一个文件中,你会看到我的我们的......

于 2012-05-23T12:31:57.480 回答
3

区分可见性寿命很重要。

使用or声明的变量的可见性是相同的。您可以在声明之后的第一个大括号或文件结尾之前的任何位置使用该名称。ourmy

请注意,这不适用于完全限定的变量名,它不需要声明并且可以在任何地方访问。在不声明任何内容的情况下,我可以分配给包变量

$pack::three = 3;

并在任何包中的其他任何地方使用它。我什至不必申报pack包裹。但如果我写

package pack;
our $three;

我已经生成了一个缩短的别名$pack::three我可以在同一个词法范围内使用它,因为我可以my在同一个地方使用一个变量:在一个封闭的大括号或文件结尾之前。

这些包变量在程序执行开始时始终可用。就像哈希元素一样,您总是可以分配给一个新元素,并且它会一直存在——它们的生命周期是无穷无尽的。事实上,包变量所有意图和目的的哈希元素。

my另一方面,用 声明的词法变量在声明时创建,一旦超出范围就销毁,并且在任何地方都没有对它们的引用。因此,除非您引用此类变量,否则它的生命周期与它的可见性相同。循环内的my声明会导致为每次执行循环创建和销毁一个新变量。

$val在您的代码中,您为包变量$one::val和词法变量创建了一个别名$new。两者都不在代码块内,因此两者在文件末尾都是可见的。package two此处根本没有任何效果,但如果您在第二个包语句之后编写,our $val 将更改别名$val来指示$two::val

我希望这会有所帮助。

于 2012-05-23T13:10:44.917 回答