6

为什么会打印 42:

$answer = 42;
$variable = "answer";

print ${$variable} . "\n";

但这不是:

my $answer = 42;
my $variable = "answer";

print ${$variable} . "\n";
4

4 回答 4

15

只有包变量(在您的第一个示例中声明的那种)可以通过符号引用定位。词法 ( my) 变量不能,这就是您的第二个示例失败的原因。

有关Perl 中两个独立变量系统的运行方式,请参阅出色的文章Coping with Scope 。并查看同样出色的为什么使用变量变量名是愚蠢的,以了解为什么这很愚蠢。:)

于 2010-02-25T23:32:29.343 回答
6

Perl 有两个完全独立但在很大程度上兼容的变量系统,包变量,如您的第一个示例,和词法变量,如第二个示例。有一些事情每个人都可以做,但另一个不能:

包变量是唯一可以是:

  1. 本地化(带local
  2. 用作符号引用的目标(OP的第二个示例不起作用的原因)
  3. 用作裸词(子定义,文件句柄)
  4. 与 typeglobs 一起使用(因为这是符号的真正含义)

词法变量是唯一可以关闭的变量(用于词法闭包)。

使用 strict 将有助于强制您使用 声明包变量our,从而使差异更加清晰。

有好几次符号引用在 Perl 中很有用,主要集中在操作符号表上(比如在模块中编写自己import的而不是使用Exporter,在运行时为模块打补丁,各种其他元编程任务)。所有这些都是高级主题。

对于其他任务,通常有更好的方法来完成它,例如使用哈希。一般的经验法则是始终运行,use warnings; use strict;除非您知道除了禁用一部分编译指示(例如no strict 'refs';在尽可能小的范围内使用)之外别无他法。

于 2010-02-25T23:27:06.467 回答
5

问题是您不能使用符号引用来引用词法变量。在这两个示例${$variable}中都在寻找$main::answer. 在第一个中,$answer是一个包 global 并且是 的缩写$main::answer,所以参考找到了它。第二个,$answer是一个词法变量,不存在于任何包中,所以引用找不到它。

perlref中的更多细节在标题符号引用下。

于 2010-02-25T23:29:19.630 回答
5

符号引用仅适用于包变量。符号表不跟踪词法变量(这是词法变量的全部意义:)。

于 2010-02-25T23:34:01.680 回答