在 Perl 5 中获取 switch/case 行为

问题描述 投票:0回答:6

在 Perl 5 中是否有一种简洁的方式来创建 case 或 switch 语句?在我看来,他们应该在版本 6 上添加一个开关。

我需要在脚本中使用此控制结构,并且我听说您可以导入“开关模块”。但是,如何在不导入的情况下实现它,以最大程度地减少依赖性并获得可移植性?

perl switch-statement
6个回答
59
投票

如果您使用 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)可以通过源过滤器为您提供虚假的 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; }
}

20
投票

Programming Perl 中的建议是:


for ($string) {
    /abc/ and do {$abc    = 1; last;};
    /def/ and do {$def    = 1; last;};
    /xyz/ and do {$xyz    = 1; last;};
    $nothing = 1;
}

11
投票

只是关于核心 Switch 模块的简短评论,该模块已在答案中多次提及。有问题的模块依赖于源过滤器。除此之外,这可能会导致报告错误的错误行。太糟糕了,没有一个核心开发人员真正记得或关心记住为什么它首先被接受到 Perl 核心中。

此外,Switch.pm 将是第一个从 Perl 核心中删除的 Perl 模块。 Perl 的下一个主要版本 5.12.0 仍将保留它,尽管有弃用警告。如果您从 CPAN 显式安装 Switch.pm,则该弃用警告将会消失。 (你会得到你想要的。)在下一个版本 5.14 中,Switch.pm 将从核心中完全删除。


9
投票

我喜欢的一个等效解决方案是调度表

my $switch = {
  'case1' => sub { print "case1"; },
  'case2' => sub { print "case2"; },
  'default' => sub { print "unrecognized"; }
};
$switch->{$case} ? $switch->{$case}->() : $switch->{'default'}->();

1
投票
print("OK : 1 - CANCEL : 2\n");
my $value = <STDIN>;
SWITCH: {
    ($value == 1) && last(SWITCH);
    ($value == 2) && do {print("Cancelled\n"); exit()};
    print("??\n");
}

0
投票

当 Perl

v5.42
发布时,现有的
given
when
将消失。

如果您想使用

Switch::Right
given
语法,但具有更合理的智能匹配,并且与现有功能具有“足够好”的向后兼容性:
when

	
© www.soinside.com 2019 - 2024. All rights reserved.