tjw*_*992 2 perl for-loop constants infinite-loop
我正在研究一个相当不确定的问题,即当你想要进行无限循环时,是否最好使用(;;)或while(1),我在C中看到了一个有趣的解决方案,你可以将#define"永远"作为常量等于 ";;" 字面上循环for(EVER).
我知道定义一个额外的常量可能不是最好的编程实践,但纯粹出于教育目的,我想看看是否可以用Perl完成.
我试图使Perl等效,但它只循环一次然后退出循环.
#!/usr/bin/perl -w
use strict;
use constant EVER => ';;';
for (EVER) {
print "FOREVER!\n";
}
Run Code Online (Sandbox Code Playgroud)
输出:
FOREVER!
Run Code Online (Sandbox Code Playgroud)
为什么这不适用于perl?
它不会永远运行,因为它';;'是一个普通的字符串,而不是一个预处理器宏(Perl没有等效的C预处理器).因此,for (';;')运行一次,$_设置为';;'一次.
C的预处理器常量与大多数语言中的常量非常不同.
一个常规常量就像一个变量,你只能设置一次; 它有一个值,可以在变量可以在大多数地方传递,有一些好处,你和编译器知道它不会改变.这是Perl常量pragma为您提供的常量类型.将常量传递给for运算符时,它只是将其视为字符串值,并相应地运行.
但是,C有一个在编译器甚至看到代码之前运行的步骤,称为预处理器.这实际上操纵了源代码的文本而不知道或关心它的大部分含义,因此可以做各种你在语言本身无法做到的事情.在这种情况下#DEFINE EVER ;;,您告诉预处理器替换每次出现的EVERwith ;;,以便在实际编译器运行时,它只能看到for(;;).你可以更进一步,将单词定义forever为for(;;),它仍然可以工作.
正如Andrew Medico在评论中所提到的,最接近Perl的预处理器是源过滤器,实际上手册中的一个例子是仿真#define.这些实际上甚至比预处理器宏更强大,允许人们编写像Acme :: Bleach这样的模块(用空格替换你的整个程序,同时保持功能)和Lingua :: Romana :: Perligata(解释用语法正确的拉丁语编写的程序) ,以及更明智的功能,如为类和方法声明添加关键字和语法.