在 Perl 5 中是否有一种简洁的方式来创建 case 或 switch 语句?在我看来,他们应该在版本 6 上添加一个开关。
我需要在脚本中使用此控制结构,并且我听说您可以导入“开关模块”。但是,如何在不导入的情况下实现它,以最大程度地减少依赖性并获得可移植性?
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)可以通过源过滤器为您提供虚假的 switch 语句,但据我所知,它是脆弱:
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; }
}
Programming Perl 中的建议是:
for ($string) {
/abc/ and do {$abc = 1; last;};
/def/ and do {$def = 1; last;};
/xyz/ and do {$xyz = 1; last;};
$nothing = 1;
}
只是关于核心 Switch 模块的简短评论,该模块已在答案中多次提及。有问题的模块依赖于源过滤器。除此之外,这可能会导致报告错误的错误行。太糟糕了,没有一个核心开发人员真正记得或关心记住为什么它首先被接受到 Perl 核心中。
此外,Switch.pm 将是第一个从 Perl 核心中删除的 Perl 模块。 Perl 的下一个主要版本 5.12.0 仍将保留它,尽管有弃用警告。如果您从 CPAN 显式安装 Switch.pm,则该弃用警告将会消失。 (你会得到你想要的。)在下一个版本 5.14 中,Switch.pm 将从核心中完全删除。
我喜欢的一个等效解决方案是调度表。
my $switch = {
'case1' => sub { print "case1"; },
'case2' => sub { print "case2"; },
'default' => sub { print "unrecognized"; }
};
$switch->{$case} ? $switch->{$case}->() : $switch->{'default'}->();
print("OK : 1 - CANCEL : 2\n");
my $value = <STDIN>;
SWITCH: {
($value == 1) && last(SWITCH);
($value == 2) && do {print("Cancelled\n"); exit()};
print("??\n");
}