6

伙计们,我有点困惑,当我遇到这个时,我正在使用 Perl 进行范围界定:

#! usr/bin/perl
use warnings;
use strict;

sub nested {
   our $x = "nested!";
}

print $x;     # Error "Variable "$x" is not imported at nested line 10."
print our $x; # Doesn't print "nested!"
print our($x) # Doesn't print "nested!"

但是当我这样做时:

{
   our $x = "nested";
}

print our($x);  # Prints "nested"
print our $x;   # Prints "nested"
print $x;       # Prints "nested"

所以你们能向我解释为什么这些有效而不是无效吗?

4

2 回答 2

6

重申DVK的答案,our只是一个方便的别名工具。您在这些示例中使用的每个变量实际上都命名为$main::x. 在任何词法范围内,您都可以our在同一范围内使用缩短的名称为该变量创建别名;该变量不会在外部重置或删除,只有别名。这与my使新变量绑定到该词法范围的关键字不同。

于 2013-06-13T02:59:25.130 回答
5
  1. 为了解释块示例为什么会这样工作,让我们看一下“现代 Perl”一书第 5 章our的解释

    我们的范围

    在给定的范围内,使用我们的内置函数声明包变量的别名。
    完全限定名称随处可用,但词法别名仅在其范围内可见。

    这解释了为什么第二个示例的前两个打印有效(我们在 print 的范围内重新声明),而第三个无效(因为我们唯一的别名 $x 到块范围内的包变量)。请注意,打印$main::x 正常工作 - 它只是作用域为块的别名,而不是包变量本身。


  2. 至于功能:

    • print our $x;print our($x)“不工作” - 即正确声明该值未初始化- 因为您从未调用过初始化变量的函数。观察差异:

      c:\>perl -e "use strict; use warnings; sub x { our $x = 1;} print our $x"
      Use of uninitialized value $x in print at -e line 1.
      
      c:\>perl -e "use strict; use warnings; sub x { our $x = 1;} x(); print our $x"
      1
      
    • print $x;由于与块相同的原因将无法工作 -our仅将别名的范围限定为块(即在这种情况下为子块的主体)因此您必须在主块的范围内重新命名它(如print our $x示例),或者在子外部使用完全限定的全局包,在这种情况下,它将按预期运行:

      c:\>perl -e "use strict; use warnings;  sub x { our $x = 1;}  print  $main::x"
      Use of uninitialized value $x in print at -e line 1.
      
      c:\>perl -e "sub x { our $x = 1;} x(); print  $main::x"
      1
      
于 2013-06-13T02:47:25.670 回答