Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl中变量的作用域_Perl - Fatal编程技术网

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";

我是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";       #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
特定于它在中使用的闭包,因此可以使用in
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
}
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