Perl中变量的作用域
我是Perl新手,对子例程中变量的用法有疑问Perl中变量的作用域,perl,Perl,我是Perl新手,对子例程中变量的用法有疑问 #! /usr/bin/perl $x=4; &routine; print "value of x in main is $x\n"; sub routine { local $x = 10; print "value of x in routine is $x\n"; print "value of x in main is $x\n";
#! /usr/bin/perl
$x=4;
&routine;
print "value of x in main is $x\n";
sub routine
{
local $x = 10;
print "value of x in routine is $x\n";
print "value of x in main is $x\n"; #what should be replaced in $x to get correct answer
}
在程序中,这一行应该替换什么
print "value of x in main is $x\n";
要获取主函数中$x变量的值?的“local”语句有效地隐藏了全局变量的原始值。如果您需要原始值,则必须在“本地”声明之前制作一份副本:
$x=4;
&routine;
print "value of x in main is $x\n";
sub routine
{
my $originalX = $x;
local $x = 10;
print "value of x in routine is $x\n";
print "value of x in main is $originalX\n";
}
与“my”相对的“local”最有用的特性是,在从局部变量范围内调用的函数中,局部值仍然可见
our $x=4;
foo();
print "value of x in main is $x\n";
sub foo {
local $x = 10;
print "value of x in foo is $x\n";
bar();
}
sub bar {
print "value of x in bar is $x\n";
}
导致
value of x in foo is 10
value of x in bar is 10
value of x in main is 4
“local”语句有效地隐藏了全局变量的原始值。如果您需要原始值,则必须在“本地”声明之前制作一份副本:
$x=4;
&routine;
print "value of x in main is $x\n";
sub routine
{
my $originalX = $x;
local $x = 10;
print "value of x in routine is $x\n";
print "value of x in main is $originalX\n";
}
与“my”相对的“local”最有用的特性是,在从局部变量范围内调用的函数中,局部值仍然可见
our $x=4;
foo();
print "value of x in main is $x\n";
sub foo {
local $x = 10;
print "value of x in foo is $x\n";
bar();
}
sub bar {
print "value of x in bar is $x\n";
}
导致
value of x in foo is 10
value of x in bar is 10
value of x in main is 4
这里有一些关于变量以及perl如何处理和使用它们的内容需要理解 当您声明
$x
并分配值4
时,实际上是在定义一个包变量。当不使用strict
pragmas(通过使用use strict'vars
或use strict
启用)时,您不必使用my
或our
进行变量声明。因此,Perl将默认初始化$x
作为包变量。包是通过package
关键字设置的,如果省略了该关键字,则perl默认为main
包。这意味着您已经创建了一个名为$main::x
的包变量,其值为4
。保留在包main
中时,可以使用别名$x
表示$main::x
包变量可以在主包范围内的任何位置使用(通常称为全局变量),这就是为什么您可以在子例程例程()
中访问$x
local
将存储$x
在其声明的作用域期间的值,直到其声明的作用域结束。因此,在您的示例中,local
声明的范围是整个routine()
(在使用local
和routine()
声明的结束}
括号之间)。离开作用域时,它会将$x
重新初始化为存储值。这就是为什么调用routine()
后的print语句将$x
显示为4
首先要回答您眼前的问题:
由于local
特定于它在中使用的闭包,因此可以使用inroutine()
创建单独的闭包。这样,您可以在该范围内本地化$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
}
sub routine {
my $y = 20;
print "y is set to $y during the duration of routine()\n";
}
如其他答案所述,perl的最佳实践是使用严格的pragmas,并在检测到错误编码时发出警告:
use strict;
use warnings 'all';
因此,运行代码将提供:
全局符号“$x”需要显式的包名
我们可以通过两种方式解决这个问题,我们可以使用包名声明它:
$main::x = 4;
然后必须在代码的其余部分将其隐式引用为$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
routine() x is 20
another_routine() x is 4
我们没有涉及由my
关键字(有时称为私有变量或my变量)声明的开放词汇变量。它们的行为是不同的,它们只在范围内生存(从技术上讲,直到它们的引用计数变为0,但这是另一个主题!)。这允许我们声明变量,这些变量(例如)仅在routine()
子例程中创建和使用:
#! /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
}
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() localized, x is 10
another_routine() still localized, x is 10
routine() x is 4
routine() x is 20
another_routine() x is 4
routine()
内部的x
是routine()
私有的,并且只有routine()
我希望语言清晰易懂 关于变量以及perl如何处理和使用变量,这里有几点需要了解 当您声明
$x
并分配值4
时,实际上是在定义一个包变量。当不使用strict
pragmas(通过使用use strict'vars
或use strict
启用)时,您不必使用my
或our
进行变量声明。因此,Perl将默认初始化$x
作为包变量。包是通过package
关键字设置的,如果省略了该关键字,则perl默认为main
包。这意味着您已经创建了一个名为$main::x
的包变量,其值为4
。保留在包main
中时,可以使用别名$x
表示$main::x
包变量可以在主包范围内的任何位置使用(通常称为全局变量),这就是您可以访问$x