有几件事情需要在这里了解关于变量,以及Perl中,并使用它们。
当您声明$x
并指定值4
时,您实际上是在定义一个包变量。如果不使用strict
编译指示(通过使用use strict 'vars'
或use strict
启用),则不必在变量声明前面加上my
或our
。因此,Perl将默认初始化为$x
作为包变量。软件包通过package
关键字设置,如果省略,那么perl默认为main
软件包。这意味着您创建了一个名为$main::x
的包变量,其值为4
。在保留包main
的同时,您可以使用别名$x
来表示$main::x
。
包变量可以在你的主包范围内的任何地方使用的(通常被称为全局变量),这就是为什么你可以在子程序routine()
访问$x
。
local
将在声明的范围期间存储$x
的值,直到它声明的范围结束。因此,在您的示例中,local
声明的范围适用于整个范围routine()
(之间使用local
,并在routine()
声明中关闭}
大括号)。离开示波器时,它将$x
重新初始化为存储值。这就是为什么调用routine()
后的打印语句显示$x
为4
。
首先回答你眼前的问题:
因为local
是特定于它是利用在封闭,可以在routine()
创建一个单独的封用。这样,您就可以在该范围内的定位$x
,但你的子程序中保留的$x
包变量:
#! /usr/bin/perl
$x=4; # declare a package variable $main::x
routine();
print "value of x in main is $x\n";
sub routine {
# now create a closure, so we can localize the package variable
# within its own scope
{
local $x = 10;
print "value of x routine, within locally scoped closure is $x\n";
}
print "value of x _from_ main is $x\n"; #will now print 4
}
在其他的答案谈到,在Perl的最佳做法是使用strict标记,以及要求警告当检测到错误的编码:
use strict;
use warnings 'all';
这样运行你的代码,然后给出:
Global symbol "$x" requires explicit package name
。
我们可以用几种方法解决这个问题,我们可以用一个包名声明它:
$main::x = 4;
然后还要implictly引用它在代码的其余部分为$main::x
。
或者,如果我们愿意有机会获得别名,我们可以使用关键字our
声明$main::x
作为一个包变量,然后把它称为$x
在我们代码的其余部分。
our $x=4; # (is the same as writing $main::x = 4, but you also
# can refer to it by its alias $x from this point onwards).
有了这些点覆盖,那么你可以有最终的推荐方案:
#! /usr/bin/perl
use strict;
use warnings 'all';
our $x=4; # declare a package variable $main::x
routine();
print "value of x in main is $x\n";
sub routine {
# now create a closure, so we can localize the package variable
# within its own scope
{
local $x = 10;
print "value of x routine, within locally scoped closure is $x\n";
}
print "value of x _from_ main is $x\n"; # will now print 4
}
额外信息
注意局部变量保持在范围内,即使其他子程序中调用那范围:
our $x=4;
routine();
sub routine {
{
local $x = 10;
print "routine() localized, x is $x\n";
another_routine();
}
print "routine() x is $x\n";
}
sub another_routine {
print "another_routine() still localized, x is $x\n";
}
将输出:
routine() localized, x is 10
another_routine() still localized, x is 10
routine() x is 4
我们都没有碰过开放词法变量由my
关键字(有时被称为私有变量或我的变量)声明。这些行为是不同的,他们只活过他们在范围内的期限(技术上直到他们的引用计数变为0,但这是另一个话题!)。这使我们能够宣布其(例如)只得到您的routine()
子程序期间创建和使用的变量:
sub routine {
my $y = 20;
print "y is set to $y during the duration of routine()\n";
}
my
也有让我们重新使用包变量名的潜移默化的影响,并使用私人 。该变量,因为他们在被宣布范围的持续时间值注意,他们没有表现得像局部变量和范围内调用其他程序会默认使用包变量值:
our $x=4;
routine();
sub routine {
my $x = 20;
print "routine() x is $x\n";
another_routine();
}
sub another_routine {
print "another_routine() x is $x\n";
}
将输出:
routine() x is 20
another_routine() x is 4
$x
内routine()
是私人到routine()
只有routine()
。
我希望lanuague足够清楚明白!
你期望打印'10'和'4'的值吗? –