在编写此程序之前,我认为our
是包范围变量,而my
是。{1}}
文件范围变量。但是,完成该程序后,我感到困惑。
我的节目是,
#!/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
之间有什么区别。两者是相同还是有差异?
答案 0 :(得分:20)
如您所见,my
和our
都有词汇效应。
my
创建一个词法范围的变量。
our
为包变量创建了一个词法范围的 别名 。
仅仅因为你说package
无法改变词汇范围,所以即使看过$val
语句,你的$one::val
仍然是package two
的别名。< / p>
如果您没有看到近似卷曲,则表示您尚未完成范围。 (或EOF或字符串eval
中的字符串结尾)。
答案 1 :(得分:6)
my 限制变量访问最内层的块 他们被宣布了。如果没有块,则它们是文件范围的。
我们的代替关联 当前包中包含变量的简单名称,因此它在包级别声明并链接到包名称。 我们的尝试通过让您使用包变量而不添加包名称来提供帮助。
package pack;
our $variable; # These are the same
$pack::variable; # These are the same
我们的变量类似于C的静态变量,但是不同,因为函数外部的我们的声明的变量仍然可以在函数外部访问使用变量的完全限定名称。
但是最重要的是我的是词汇范围的,而我们的是词汇范围,但是他们的生命甚至在声明区之外仍然存在(他们的生活就像全局变量生命),因此要真正理解我的和我们的之间的区别,您必须了解Perl中词法和全局范围之间的区别。
简单地说,两种类型之间的区别是:
任何地方的任何代码都可以更改其值。
变量的生命周期与代码块的结尾包含在内,之后它们的值被垃圾收集。这些变量只能在声明它们的块中访问。
要回答您具体的示例问题: 尝试将第二个包声明(包2)移动到另一个文件中,您将看到 my 和我们的 ...
答案 2 :(得分:3)
区分可见性和生命周期非常重要。
使用our
或my
声明的变量的可见性是相同的。您可以在第一个封闭括号或文件结尾之前的声明之后的任何位置使用该名称。
请注意,这不适用于完全限定的变量名称,它们不需要声明,可以在任何地方访问。没有声明任何我可以分配给包变量
$pack::three = 3;
并在任何包中的任何其他位置使用它。我甚至不必声明pack
包。但如果我写
package pack;
our $three;
我为$pack::three
生成了一个缩短的别名,我可以在同一个词法范围内使用,因为我可以在同一个地方使用my
变量:在一个封闭的大括号之前或文件结尾。
这些包变量始终在程序执行开始时可用。就像哈希元素一样,你总是可以分配给一个新元素,它总是在那里 - 它们的生命周期是无穷无尽的。实际上,包变量是所有意图和目的的哈希元素。
另一方面,用my
声明的词汇变量是在声明点创建的,一旦超出范围就被销毁,并且没有任何引用它们。因此,除非您参考此类变量,否则其生存期与其可见性相同。循环内的my
声明会导致为循环的每次执行创建和销毁新变量。
在您的代码中,您为包变量$val
和词法变量$one::val
创建了别名$new
。两者都不在代码块中,因此两者都可以在文件末尾看到。 package two
在这里完全没有效果,但如果您在第二个包语句之后编写了our $val
,那么您将更改别名$val
以指示{{ 1}}而不是。
我希望有所帮助。