在Perl 5中是否有一种简洁的方法来制作case或switch语句?在我看来,他们应该在版本6上包含一个开关..
我在脚本中需要这个控制结构,我听说你可以导入一个“开关模块”。但是如何在没有导入的情况下实现它以最小化依赖性并获得可移植性?
答案 0 :(得分:57)
如果您使用的是Perl 5.10,那么given
/when
就是一个switch语句(注意,它可以做的不仅仅是与正则表达式进行比较,请阅读链接的文档以了解它的全部潜力):
#or any of the dozen other ways to tell 5.10 to use its new features
use feature qw/switch/;
given($string) {
when (/^abc/) { $abc = 1; }
when (/^def/) { $def = 1; }
when (/^xyz/) { $xyz = 1; }
default { $nothing = 1; }
}
如果您使用的是Perl 5.8或更早版本,则必须使用if
/ elsif
/ else
语句:
if ($string =~ /^abc/) { $abc = 1; }
elsif ($string =~ /^def/) { $def = 1; }
elsif ($string =~ /^zyz/) { $xyz = 1; }
else { $nothing = 1; }
$string =~ /^abc/ ? $abc = 1 :
$string =~ /^def/ ? $def = 1 :
$string =~ /^xyz/ ? $xyz = 1 :
$nothing = 1;
Core Perl(Switch)中有一个模块可以通过source filters为您提供虚假的切换语句,但我理解它是fragile:
use Switch;
switch ($string) {
case /^abc/ {
case /^abc/ { $abc = 1 }
case /^def/ { $def = 1 }
case /^xyz/ { $xyz = 1 }
else { $nothing = 1 }
}
或替代语法
use Switch 'Perl6';
given ($string) {
when /^abc/ { $abc = 1; }
when /^def/ { $def = 1; }
when /^xyz/ { $xyz = 1; }
default { $nothing = 1; }
}
答案 1 :(得分:17)
编程Perl的建议是:
for ($string) {
/abc/ and do {$abc = 1; last;};
/def/ and do {$def = 1; last;};
/xyz/ and do {$xyz = 1; last;};
$nothing = 1;
}
答案 2 :(得分:9)
关于核心Switch模块的简短评论,已在答案中多次提及。有问题的模块依赖于源过滤器。除此之外,这可能导致报告错误的错误行。这是非常糟糕的,没有一个核心开发人员真正记得或关心为什么它首先被接受到perl核心。
此外,Switch.pm将是有史以来第一个从perl核心中删除的Perl模块。 perl的下一个主要版本5.12.0仍将拥有它,尽管有弃用警告。如果您从CPAN明确安装Switch.pm,那么弃用警告将消失。 (你得到了你要求的东西。)在下一个版本中,5.14,Switch.pm将完全从核心中删除。
答案 3 :(得分:8)
我喜欢的等效解决方案是dispatch table。
my $switch = {
'case1' => sub { print "case1"; },
'case2' => sub { print "case2"; },
'default' => sub { print "unrecognized"; }
};
$switch->{$case} ? $switch->{$case}->() : $switch->{'default'}->();
答案 4 :(得分:0)
print("OK : 1 - CANCEL : 2\n");
my $value = <STDIN>;
SWITCH: {
($value == 1) && last(SWITCH);
($value == 2) && do {print("Cancelled\n"); exit()};
print("??\n");
}