我知道my
Perl中有什么.它定义了一个仅存在于定义它的块范围内的变量.怎么our
办?有our
什么不同my
?
好问题:如何our
区别my
和做our
什么?
综上所述:
从Perl 5开始提供,my
是一种声明:
非包装变量,即
私人的,
新的,
非全局变量,
与任何包裹分开.这样就无法以形式访问变量$package_name::variable
.
另一方面,our
变量是:
包变量,因此自动
全局变量,
绝对不是私人的,
它们也不一定是新的; 和他们
可以使用限定名称空间在包(或词法范围)外部访问,如$package_name::variable
.
声明变量our
允许您预先声明变量以便在use strict
不使用拼写错误警告或编译时错误的情况下使用变量.从Perl 5.6开始,它已经取代了过时的use vars
,它只是文件范围的,而不是按字面顺序排列our
.
例如,$x
内部变量的正式限定名称package main
是$main::x
.当脚本使用或时,声明our $x
允许您$x
在声明的范围内使用裸变量而不会受到惩罚(即,没有产生错误).范围可能是一个,两个或更多个包,或一个小块.use strict
use strict "vars"
来自cartman和Olafur的PerlMonks和PerlDoc链接是一个很好的参考 - 下面是我的总结:
my
{}
如果不是在{}
s中,则变量在由同一文件定义的单个块内的词法范围内.它们不能从相同词法范围/块之外定义的包/子例程访问.
our
变量在包/文件中作用域,并且可以从任何代码use
或require
包/文件中访问 - 通过在相应的名称空间之前添加名称冲突.
为了完善它,local
变量是"动态"范围的,与my
变量不同,因为它们也可以从同一块内调用的子程序访问.
一个例子:
use strict; for (1 .. 2){ # Both variables are lexically scoped to the block. our ($o); # Belongs to 'main' package. my ($m); # Does not belong to a package. # The variables differ with respect to newness. $o ++; $m ++; print __PACKAGE__, " >> o=$o m=$m\n"; # $m is always 1. # The package has changed, but we still have direct, # unqualified access to both variables, because the # lexical scope has not changed. package Fubb; print __PACKAGE__, " >> o=$o m=$m\n"; } # The our() and my() variables differ with respect to privacy. # We can still access the variable declared with our(), provided # that we fully qualify its name, but the variable declared # with my() is unavailable. print __PACKAGE__, " >> main::o=$main::o\n"; # 2 print __PACKAGE__, " >> main::m=$main::m\n"; # Undefined. # Attempts to access the variables directly won't compile. # print __PACKAGE__, " >> o=$o\n"; # print __PACKAGE__, " >> m=$m\n"; # Variables declared with use vars() are like those declared # with our(): belong to a package; not private; and not new. # However, their scoping is package-based rather than lexical. for (1 .. 9){ use vars qw($uv); $uv ++; } # Even though we are outside the lexical scope where the # use vars() variable was declared, we have direct access # because the package has not changed. print __PACKAGE__, " >> uv=$uv\n"; # And we can access it from another package. package Bubb; print __PACKAGE__, " >> main::uv=$main::uv\n";
应对范围界定是对Perl范围规则的一个很好的概述.它已经够老了,our
在文本正文中没有讨论过.它在最后的注释部分中讨论.
本文讨论了包变量和动态范围,以及它与词法变量和词法范围的区别.
my用于局部变量,其中我们用于全局变量.更多关于Perl中变量范围的阅读:基础知识.
我曾经在Perl中遇到过一些关于词汇声明的陷阱,这些陷阱使我感到困惑,这些陷阱也与此问题有关,因此我在这里添加摘要:
1.定义还是声明?
local $var = 42; print "var: $var\n";
输出为var: 42
。但是,我们无法确定local $var = 42;
是定义还是声明。但是呢:
use strict; use warnings; local $var = 42; print "var: $var\n";
第二个程序将引发错误:
Global symbol "$var" requires explicit package name.
$var
没有定义,这意味着local $var;
只是一个声明!在local
用于声明变量之前,请确保之前已将其定义为全局变量。
但是为什么这不会失败?
use strict; use warnings; local $a = 42; print "var: $a\n";
输出为:var: 42
。
这是因为$a
和一样$b
,也是Perl中预定义的全局变量。还记得排序功能吗?
2.词汇还是全局?
在开始使用Perl之前,我是一名C程序员,所以词法和全局变量的概念对我来说似乎很简单:它只对应于C中的自动变量和外部变量。但是有一些小的区别:
在C语言中,外部变量是在任何功能块外部定义的变量。另一方面,自动变量是在功能块内部定义的变量。像这样:
int global; int main(void) { int local; }
在Perl中,事情很微妙:
sub main { $var = 42; } &main; print "var: $var\n";
输出为var: 42
。$var
是全局变量,即使它是在功能块中定义的!实际上,在Perl中,默认情况下任何变量都声明为全局变量。
该课程始终是use strict; use warnings;
在Perl程序的开头添加的,这将迫使程序员显式声明词法变量,这样我们就不会为理所当然的一些错误所迷惑。