我有以下常数:
use constant => 7
是否有一个选项可以通过标量变量设置常量一次,然后常量的值将是初始化值,即如下所示:
use constant => $scalar
- >那么从现在开始的常数在这一点上具有标量值
任何建议?
答案 0 :(得分:7)
使用use constant
创建的常量在编译时处理,因此$scalar
变量可能尚未分配任何值。
然而,您可以使用Const::Fast
模块制作标量 - 井 - 常数:
use Const::Fast;
my $scalar = 7;
const my $constant => $scalar;
$constant = 42; # dies
这比use constant
更可取,因为它处理const标量比处理常量(实现为特殊子程序)更好。例如,可以将const标量插入到字符串中。
但是,编译时常量参与常量折叠优化。在某些情况下,这实际上是必要的,因此use constant
的一些用途仍然存在。
(如果你不能使用Const::Fast
,那么Readonly
是另一种选择,虽然速度较慢)
答案 1 :(得分:4)
是的,你可以。当然,您必须尽快将值分配给标量。
my $foo;
BEGIN {
...
...
$foo = ...;
}
use constant FOO => $foo;
您也可以使用do
。
use constant FOO => do {
...
...
...
};
答案 2 :(得分:2)
通过创建一个返回常量值的子例程,在编译时创建常量。
例如:
use constant PI => 3.1415169;
与此类似:
sub PI {
return 3.1415169;
}
问题是常量很难在各种情况下使用,例如正则表达式或带引号的字符串。有一种秘密的,模糊的内插常量的方法(这种方法也适用于其他类型的子程序。你可以在@{[...]}
内嵌入常量:
say "The value of pi is equal to @{[PI]}.";
# Replace value of Pi in Alabama: http://www.snopes.com/religion/pi.asp
$foo = s/@{[PI]}/3/g;
丑陋不是吗?
另一种方法是使用类型globs:
*PI = \3.1415926;
our $PI;
这会插入:
say "The value of pi is $PI."
但是,除了标量之外的其他任何东西都不能很好地运作。您可以定义数组和散列,但它们不是常量值。
幸运的是,有许多方法可以定义更像变量的常量。不幸的是,有很多种方法来定义更像变量的常量,并且Perl没有附带的标准模块。这意味着您必须在需要运行脚本的每个系统上安装一些可选的CPAN模块。如果它们在公司服务器上,您可能需要有人为您安装模块。
另外,由于每个人都有自己喜欢的常规例程,因此最终可能会安装多个模块:
最受欢迎的是Readonly:
use Readonly;
# For Perl 5.8 and later...
Readonly my $pi => 3.1415926;
它快速而简单,但Readonly可能很慢,除非你也安装了Readonly:XS,如果你没有C编译器和Make,那么Readonly :: XS可能很难安装。一个名为Const::Fast的新模块也很受欢迎:
use Const::Fast;
const my PI => 3.1415926;
say "The value of pi is $pi.";
所以,你有它。
use constant;
这是一个标准模块,因此您知道它始终可用。但是,它不容易插值。您可以使用@{[...]}
语法,但这很难看。