Perl有枚举类型吗?

Perl有枚举类型吗?,perl,enums,Perl,Enums,Perl是否有遵循最佳实践的枚举类型,或者更重要的是,它是否需要枚举类型 我正在工作的项目之一使用字符串来表示通常在C#之类的语言中使用枚举的东西。例如,我们在哈希数组中有一组电话号码,每个号码都与电话类型(“家庭”、“工作”、“手机”等)相关: 在这里使用一组只读变量就足够了,还是应该使用枚举?我发现了一个,但它似乎使用了违反其中一个的赤裸裸的话。我对使用的想法是这样的: use Readonly; Readonly my $HOME => 'Home'; Readonly my

Perl是否有遵循最佳实践的枚举类型,或者更重要的是,它是否需要枚举类型

我正在工作的项目之一使用字符串来表示通常在C#之类的语言中使用枚举的东西。例如,我们在哈希数组中有一组电话号码,每个号码都与电话类型(“家庭”、“工作”、“手机”等)相关:

在这里使用一组只读变量就足够了,还是应该使用枚举?我发现了一个,但它似乎使用了违反其中一个的赤裸裸的话。我对使用的想法是这样的:

use Readonly;

Readonly my $HOME   => 'Home';
Readonly my $WORK   => 'Work';
Readonly my $MOBILE => 'Mobile';

$phone_number->{type} = $HOME;

这是一个好方法还是有更好的方法?

Perl本机不支持这个概念,但有一些模块可以添加此功能


你的方式已经足够了


如果您碰巧使用Moose,还可以使用Moose::Util::TypeConstraints创建枚举。(您应该是。)

不,没有内置的枚举构造。Perl没有做很多严格的类型化工作,所以我认为实际上几乎不需要这样做

在我看来,你采用的方法是可靠的

还有更传统的布拉格语

在幕后,它为每个返回值的常量设置一个函数,如下所示

sub HOME () { 'Home' }
我会坚持,除非你想利用这一优势,例如:

package Phone::Type;

use constant {
    HOME => 'Home',
    #...
};

package main;

print Phone::Type->HOME, "\n";

Perl实际上有一个类似于C的枚举类型

例如:

use enum qw(HOME WORK MOBILE);
现在我们有:

HOME == 0
WORK == 1
MOBILE == 2
HOME == 0
WORK == 1
MOBILE == 10
FAX == 11
您也可以自己设置索引:

use enum qw(HOME=0 WORK MOBILE=10 FAX);
现在我们有:

HOME == 0
WORK == 1
MOBILE == 2
HOME == 0
WORK == 1
MOBILE == 10
FAX == 11
寻找更多细节


请注意,并非每个Perl版本都支持这一点。我知道v5.8.3不支持它,而v5.8.7支持它。

对于这些枚举和命名常量,perl恐怕是完全瘫痪的:

  • enum和Readonly不是核心模块(至少是Perl5.8,我刚刚检查过)。因此,在无法自由安装新模块的系统上,这些功能可能不可用

  • “use Constant”和“use strict”(应该始终使用)完全不可用,因为它会生成大量可怕的错误消息,形式如下:

    使用“strict subs”时不允许使用裸字“FRED”


让我们希望他们已经在perl 6中解决了这一问题,如果它真的出现的话

这对我很有效

use constant MYENUM => qw(ZERO ONE TWO THREE FOUR);

BEGIN {
    eval "use constant (MYENUM)[$_] => $_;" foreach 0..(MYENUM)-1;
}

然后,您可以使用
0、1、2
等作为常量,并使用
(MYENUM)[$value]

打印出它们的符号名。为了严格起见,在幕后制作了sub-HOME(){HOME'}。当您有一个接受Phone::Type enum作为参数的子例程时,如何对子例程参数is Phone::Type Type enum,而不是string,而不是number…执行动态检查只是为了澄清sub HOME(){HOME'}并使用常量{HOME=>'HOME',WORK=>'WORK',MOBILE=>'MOBILE',};都一样吗?后者(在幕后)生成代码?您的示例不匹配;-),但是,是的,目前的实施确实如此。请参阅perldoc常量中的技术注释部分。常量还进行一些名称检查。例如,不允许以双下划线开头,像“BEGIN”这样的名称会引起警告(使用警告),因为它们可能会混淆。有关详细信息,请查看通过调用“perldoc-m constant”实现的情况。这实际上与更高版本的Perl一样不准确。看这里,据我所知,
use enum
是一个CPAN模块,不是核心语言的一部分。@paul nathan。。。但我不确定这是否会妨碍某人使用它。大量的perl特性不是核心的一部分,所有其他技术都让我感到痛苦。我有大量的变量,必须将每一个都按顺序标注。然后-我的外部应用程序改变了格式,需要在列表的开头添加一个定义-因此我必须重新编号所有内容!enum模块绝对是一个不错的选择!!常量不打印警告,在5.8中也没有:
perl-e'使用严格的qw(subs);使用常量FRED=>q{FRED};printf qq{Perl%vd\n常量为%s\n},$^V,FRED'
给出
Perl 5.8.4常量为FRED
,没有警告。(是的,我知道这个答案已经有好几年了……)你应该永远记住,PBP是一本咨询性的书——这本书本身也是如此。你需要解释这些指导方针,而不是盲目地采纳它们。