有没有办法在 Perl 中使用“常量”作为哈希键?

Posted

技术标签:

【中文标题】有没有办法在 Perl 中使用“常量”作为哈希键?【英文标题】:Is there any way to use a "constant" as hash key in Perl? 【发布时间】:2010-09-10 22:38:53 【问题描述】:

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

例如:

use constant X => 1;

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

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

【问题讨论】:

【参考方案1】:

use constant 实际上是做常量子程序。

要做你想做的事,你需要显式调用sub:

use constant X => 1;

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

use constant X => 1;

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

【讨论】:

【参考方案2】:

另一种选择是不使用 use constant pragma 并按照 Damian Conway 的 Perl Best Practices 中的建议切换到 Readonly。

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

只读语法创建“正常外观”的变量,但实际上会强制保持不变或只读。您可以像使用任何其他变量一样使用它作为键。

use Readonly; Readonly my $CONSTANT => 'Some value'; $hash$CONSTANT = 1;

【讨论】:

它不是核心模块。【参考方案3】:

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

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

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

或者,您可以添加各种标点符号,以便在 => 前面不再有一个简单的单词:

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

【讨论】:

【参考方案4】:

使用$hashCONSTANT()$hash+CONSTANT 防止裸词引用机制启动。

发件人:http://perldoc.perl.org/constant.html

【讨论】:

【参考方案5】:

其他大多数人都很好地回答了您的问题。总而言之,这些内容对问题和推荐的解决方法提供了非常完整的解释。问题是 Perl pragma "use constant" 确实在您当前的包中创建了一个子例程,其名称是 pragma 的第一个参数,其值是最后一个。

在 Perl 中,一旦声明了子程序,就可以不带括号地调用它。

了解“常量”只是子例程,您可以看到为什么它们没有被插入到字符串中,以及为什么引用左侧参数的“胖逗号”运算符“=>”认为你已经给它一个字符串(尝试其他内置函数,如 time() 和 keys() 有时使用胖逗号以获得​​额外的乐趣)。

幸运的是,您可以使用明确的标点符号(如括号或 & 符号)调用常量。

但是,我有一个问题要问您:您为什么要使用常量作为哈希键?

我能想到一些可能会引导你走向这个方向的场景:

    您希望控制哪些键可以在散列中。

    您想抽象出键的名称以防以后发生更改

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

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

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

【讨论】:

【参考方案6】:

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

=>(胖逗号)如果它是一个裸字,它会自动引用左操作数,就像 $hashkey 表示法一样。

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

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

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

%hash = (X, 1);

【讨论】:

【参考方案7】:

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

尝试使用

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

【讨论】:

【参考方案8】:

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

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

另一种选择是取消 '=>' 并改用 ',':

my %x ( X, 1 );

【讨论】:

【参考方案9】:

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

完全同意 Damian Conway 的 Perl Best Practices...强烈推荐阅读。

但是,如果您打算使用 PBP 作为内部风格指南,请阅读 PBP Module Recommendation Commentary,这是一个有用的“勘误表”。

【讨论】:

谢谢你,很高兴知道。我已经离开了我的 perl 演出,所以我可能不会在家里以外的地方使用它,但我把那个链接转发给了我曾经一起工作的一个人。

以上是关于有没有办法在 Perl 中使用“常量”作为哈希键?的主要内容,如果未能解决你的问题,请参考以下文章

Perl,将数字键哈希转换为数组

使用类常量作为 Ruby 哈希键

小白学Perl之初始哈希

我可以在 R 中使用列表作为哈希吗?如果是这样,为啥这么慢?

如何在 Perl 中获取哈希的一部分?

在 Perl 中,哈希键周围的引号是一种好习惯吗?