有没有办法使用常量作为哈希键?

例如:

use constant X => 1;

my %x = (X => 'X');

上面的代码将创建一个以“X”作为键而不是 1 作为键的哈希。然而,我想使用常量 X 的值作为键。

有帮助吗?

解决方案

use constant 实际上制作了常量子程序。

要执行您想要的操作,您需要显式调用子函数:

use constant X => 1;

my %x = ( &X => 'X');

或者

use constant X => 1;

my %x = ( X() => 'X');

其他提示

另一种选择是不使用 use Constant pragma 并按照 Damian Conway 的 Perl 最佳实践中的建议切换到 Readonly。

在意识到常量哈希引用只是对哈希的常量引用后,我切换了一段时间,但不对哈希内的数据执行任何操作。

只读语法创建“看起来正常”的变量,但实际上会强制执行恒定性或只读性。您可以像将任何其他变量用作键一样使用它。


use Readonly;

Readonly my $CONSTANT => 'Some value';

$hash{$CONSTANT} = 1;

你的问题是 => 是一个神奇的逗号,它会自动引用它前面的单词。所以你写的相当于('X', 'X')。

最简单的方法是只使用逗号:

my %x = (X, 'X');

或者,您可以添加各种标点符号,这样 => 前面就不再有简单的单词了:

my %x = ( X() => 'X' );
my %x = ( &X => 'X' );

使用 $hash{CONSTANT()} 或者 $hash{+CONSTANT} 以防止裸字引用机制启动。

从: http://perldoc.perl.org/constant.html

其他大多数人都很好地回答了你的问题。总而言之,这些内容对问题进行了非常完整的解释并推荐了解决方法。问题是 Perl 编译指示“使用常量”实际上在当前包中创建了一个子例程,其名称是编译指示的第一个参数,其值是最后一个。

在 Perl 中,一旦声明了子例程,就可以在没有括号的情况下调用它。

了解“常量”只是子例程,您可以明白为什么它们没有插入字符串中,以及为什么引用左侧参数的“胖逗号”运算符“=>”认为您已经向它传递了一个字符串(尝试其他构建的-in 诸如 time() 和 keys() 之类的函数,有时带有粗逗号以获得​​额外的乐趣)。

幸运的是,您可以使用显式标点符号(例如括号或与符号)来调用常量。

不过,我有一个问题要问你:为什么你要使用常量作为哈希键?

我可以想到一些可能引导您朝这个方向发展的场景:

  1. 您希望控制哈希中可以包含哪些键。

  2. 您想要抽象键的名称,以防以后发生更改

对于第 1 个情况,常量可能不会保存您的哈希值。相反,请考虑创建一个具有公共 setter 和 getter 的类,用于填充仅对对象可见的哈希。这是一个非常不像 Perl 的解决方案,但很容易做到。

就第二点而言,我仍然强烈主张建立一个班级。如果通过定义良好的接口来管理对哈希的访问,则只有类的实现者负责获取正确的哈希键名称。在这种情况下,我根本不建议使用常量。

希望这对您有所帮助,并感谢您的宝贵时间。

use constant pragma 创建一个原型为不带参数的子例程。虽然它 看起来 就像 C 风格的常量一样,它实际上是一个返回常量值的子例程。

=> (胖逗号)如果左操作数是裸字,则自动引用左操作数,$hash{key} 表示法也是如此。

如果您对常量名称的使用看起来像一个裸字,则引用机制将启动,您将得到它的名称作为键而不是它的值。为了防止这种情况,请更改用法,使其不再是裸字。例如:

use constant X => 1;
%hash = (X() => 1);
%hash = (+X => 1);
$hash{X()} = 1;
$hash{+X} = 1;

在初始化程序中,您还可以使用普通逗号代替:

%hash = (X, 1);

=> 运算符将其左侧解释为“字符串”,就像 qw() 那样。

尝试使用

my %x = ( X, 'X');

一种方法是将 X 封装为 (X):

my %x ( (X) => 1 );

另一种选择是取消 '=>' 并使用 ',' 代替:

my %x ( X, 1 );

评论@shelfoo(声誉还不够高,无法直接在那里添加评论!)

完全同意 Damian Conway 的 Perl 最佳实践...强烈推荐阅读。

不过请阅读 PBP模块推荐评论 如果您打算使用 PBP 作为内部风格指南,那么这是一个有用的“勘误表”。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top