本质上,裸字形式只是向后兼容的历史遗产。在新代码中使用词法变量几乎总是正确的做法。
→ 顺便说一下,$x
is a 词汇标量变量, where FOO
正如你所说,称为裸词
细节/题外话
为了完整起见,正如 @Joe_Z 在评论中指出的那样,词法文件句柄对象是“相对较新的”,作为 Perl 5.005 和 5.6 之间相当大的重写的一部分(它们甚至在该版本号中获得了整个数量级......) 。
然而,从技术上讲,裸字FOO
(或者,例如STDIN
) 仅针对文件句柄在单独的命名空间中进行解释。因为没有印记(比如$ @ % &
)对于文件句柄命名空间,只有两种方法可以引用该命名空间中的文件句柄:
- 您可以在某些函数的间接对象槽中引用它,例如
print
,由于历史原因,谁会(在幕后)推断裸字必须引用文件句柄;
- 您可以使用 typeglob,例如
*FOO
,它指的是“任何名称空间中碰巧绑定到符号的任何内容FOO
.
请注意,在某些语言中,例如 C 或Scheme,单个符号没有类型符号,因此所有符号只能以一种方式绑定(例如,不能有一个名为printf
和一个名为的函数printf
在 C 中……通常),而在 Perl 或(例如)Common Lisp 中,相同的符号foo
可以绑定到许多不同的事物;区别在于 Perl 实际上要求您使用符号来消除“哪个”的歧义。foo
在大多数情况下,你的意思是“。$foo
, @foo
= @foo[ $x .. $y]
, $foo[ $n ]
, %foo
= @foo{ $k1, $k2 }
= $foo{ $k }
, &foo
等等。
但是,通过使用裸字作为文件句柄,您会失去一些能力:
值得注意的是,为了在本地或词法上(而不是全局)绑定它们,您需要绑定every每个名称空间中都有符号,因为没有可用的印记。因此,my $foo
and my @foo
可以存在于两个不同的暂存器(范围)中,其中一个可能比另一个寿命更长;但my *foo
将包括这两者以及文件句柄foo
(以及可能其他晦涩的极端情况,例如format
说明符,尽管我不会发誓)。
将裸字样式的文件句柄传递给函数等也非常困难。
基本上,裸字继承了全局作用域的所有缺点,并且没有词法变量的优点。
perldoc perldata
有一个很好的部分类型团和文件句柄这可能也更清楚地解释了这些事情。我手边没有副本,但我相信骆驼也对这个主题进行了更详细的介绍。