我知道my在Perl中是什么。它定义了一个只存在于定义它的块范围内的变量。我们该怎么做?
我们的和我的有什么不同?
我知道my在Perl中是什么。它定义了一个只存在于定义它的块范围内的变量。我们该怎么做?
我们的和我的有什么不同?
当前回答
处理作用域是对Perl作用域规则的一个很好的概述。它已经足够古老了,所以我们没有在正文中讨论。在最后的Notes一节中讨论了这个问题。
本文讨论包变量和动态作用域,以及它们与词法变量和词法作用域的区别。
其他回答
My用于局部变量,而our用于全局变量。
更多内容请参阅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没有定义,这意味着本地的$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中,任何变量都默认声明为全局变量。
教训是要时刻加用严;使用警告;在Perl程序的开始,这将迫使程序员显式地声明词法变量,这样我们就不会被一些想当然的错误弄乱。
perldoc对我们的。
与我的方法不同,我的方法既为变量分配存储空间,又将一个简单的名称与该存储空间关联起来,以便在当前作用域内使用,而我们的方法则将一个简单的名称与当前包中的一个包变量关联起来,以便在当前作用域内使用。换句话说,our具有与my相同的作用域规则,但不一定创建变量。
我们的和我的有什么不同,我们做什么?
总而言之:
my是一种声明非包变量的方法,它们是:
私人 新 非全局 与任何包分开,这样变量就不能以$package_name::variable的形式访问。
另一方面,我们的变量是包变量,因此自动:
全局变量 绝对不是私人的 不一定是新的 可以在包(或词法范围)之外使用 限定的命名空间,如$package_name::variable。
使用our声明变量允许您预先声明变量,以便在use strict下使用它们,而不会得到拼写警告或编译时错误。从Perl 5.6开始,它取代了过时的vars, vars只是文件作用域,而不像我们的那样是词汇作用域。
例如,main包中变量$x的正式限定名是$main::x。声明我们的$x允许你在声明的范围内,当脚本使用use strict或使用strict“vars”时,使用纯$x变量而没有惩罚(即,没有导致错误)。范围可以是一个、两个或多个包,或者一个小块。
print "package is: " . __PACKAGE__ . "\n";
our $test = 1;
print "trying to print global var from main package: $test\n";
package Changed;
{
my $test = 10;
my $test1 = 11;
print "trying to print local vars from a closed block: $test, $test1\n";
}
&Check_global;
sub Check_global {
print "trying to print global var from a function: $test\n";
}
print "package is: " . __PACKAGE__ . "\n";
print "trying to print global var outside the func and from \"Changed\" package: $test\n";
print "trying to print local var outside the block $test1\n";
输出:
package is: main
trying to print global var from main package: 1
trying to print local vars from a closed block: 10, 11
trying to print global var from a function: 1
package is: Changed
trying to print global var outside the func and from "Changed" package: 1
trying to print local var outside the block
如果使用"use strict"会在试图运行脚本时失败:
Global symbol "$test1" requires explicit package name at ./check_global.pl line 24.
Execution of ./check_global.pl aborted due to compilation errors.