3

我对 perl 中的 const 声明有疑问,但无法弄清楚其中的区别,请指出有什么区别。

下面是代码:

BEGIN {
  *SIZE = sub() { 2 };
}  
*ITEM = sub() { 10 };

print 'size=', SIZE, "\n";
print 'item=', &ITEM, "\n";

现在的问题是,为什么

  print 'item=', &ITEM, "\n";

行必须在 ITEM 前面有一个 '&',但是

  print 'size=', SIZE, "\n";   

行不需要在 SIZE 前面有一个 '&'。

而且我知道 BEGIN 块是在编译时运行的。

4

3 回答 3

7

因为 BEGIN 块是在编译时运行的,所以编译器知道对 的赋值*SIZE,而对 的赋值*ITEM还没有发生。

因为编译器不知道*ITEM,所以调用ITEM是不明确的,因此您必须在它前面加上一个&. 否则,编译器认为它可能是一个“裸词”——一个未加引号的字符串。

如果你use strict,编译将假定裸词是函数。

use constant也可能是声明常量的更好方法,而不是手动进行。

于 2012-04-27T11:29:20.060 回答
2

编码

BEGIN {
  *SIZE = sub() { 2 };
}  
*ITEM = sub() { 10 };

print 'size=', SIZE, "\n";
print 'item=', ITEM, "\n";

如果没有错误,将按如下方式处理:

  • 编译文件。
    • 编译BEGIN块。
      • *SIZE = sub() { 2 };
    • 执行BEGIN块。
      • *SIZE = sub() { 2 };
    • 编译*ITEM = sub() { 10 };
    • 编译print 'size=', SIZE, "\n";
    • 编译print 'item=', ITEM, "\n";
  • 执行文件。
    • 执行*ITEM = sub() { 10 };
    • 执行print 'size=', SIZE, "\n";
    • 执行print 'item=', ITEM, "\n";

注意print 'item=', ITEM, "\n";sub 存在之前是如何编译的。如果ITEM作为潜艇存在,那将是允许的。但ITEM不作为子存在。在没有任何其他含义的情况下,标识符是裸词,并且裸词被编译成具有相同值的字符串。

>perl -E"my $x = ITEM; say $x;"
ITEM

>perl -E"my $x = 'ITEM'; say $x;"
ITEM

也就是说,除非您特别要求 Perl 不这样做:

>perl -E"use strict; my $x = ITEM; say $x;"
Bareword "ITEM" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.

这意味着您需要ITEM看起来像一个子调用。

print 'item=', ITEM(), "\n";

&ITEM也可以,因为&是告诉 Perl 忽略原型的指令。

于 2012-04-27T15:36:06.357 回答
1

& 前缀明确表示“这是下一个用户定义的子例程调用”。当您在函数名称后使用括号并且函数名称与内置函数不冲突时,或者如果您在使用函数之前已声明/定义函数并且名称与内置函数不冲突,则可以省略它内置。

继续阅读这里

并检查@Sean McMillan 的回复。

于 2012-04-27T11:30:01.083 回答