Perl Switch声明

时间:2011-02-07 08:26:15

标签: perl switch-statement case conditional-statements

如果没有匹配的案例块,有没有办法运行代码块?例如:

switch($a) {

  case // {}
  case // {}
  ...
  # DO SOMETHING IF NONE OF THE ABOVE CASES WERE MATCHED
}

else不是我想要的,因为它仅适用于最后一个案例块。

10 个答案:

答案 0 :(得分:33)

Perl 5.10中总会有切换,如果你当然正在运行它。

use feature qw(switch);

given($a){
  when(1) { print 'Number one'; }
  when(2) { print 'Number two'; }
  default { print 'Everything else' }
}

答案 1 :(得分:11)

请注意,任何形式的use Switch都被弃用,因为它正在被perl自己的switch语句替换(并在下一个perl版本中删除),正如已经回答的那样:

use feature qw(switch);

given ($x)
{
when ('case1') { print 1; }
default {print 0; }
}

使用默认情况可达到您想要的结果。如果您希望在评估一个条件为true后停止评估开关,也不要忘记使用last

答案 2 :(得分:6)

我通常使用下面的块结构,它更简单,不需要导入任何东西。

SWITCH: {
    if($key =~ /^abc/) { $key = "key starts with abc"; last SWITCH; } # 'last' breaks the 'SWITCH' block
    if($key =~ /^def/) { $key = "key starts with def"; last SWITCH; }
    if($key =~ /^ghi/) { $key = "key starts with ghi"; last SWITCH; }   
    $key = "Default value";
}

print $key;

答案 3 :(得分:5)

else确实是你要找的。

switch ( $n ) {
    case 1 { print "one\n" }
    case 2 { print "two\n" }
    else   { print "other\n" }
}

以上内容会为$n=3输出“other”,为$n=1输出“one”。

答案 4 :(得分:3)

  
    

“其他不是我正在寻找的,因为它只适用于最后一个案例块。”

  

只要你没有使用直通:

use Switch 'fallthrough';

你很安全。

如果您到达最后一个案例陈述,则意味着上述案例陈述中没有一个符合条件。换句话说(如果没有直通),只有在所有case语句都无法满足条件时才会执行else语句。

答案 5 :(得分:2)

此声明返回案例2

my $test = 'abcd';

print test($test);

sub test {
    for ($_[0]) {
        /ad/ && return 'Case 1';
        /bc/ && return 'Case 2';
        /c/ && return 'Case 3';
    }
}

这一次返回案例3

my $test = 'abcd';
my $result;

for ($test) {
    /ad/ && do { $result = 'case 1' };
    /bb/ && do { $result = 'case 2' };
    /cd/ && do { $result = 'case 3' };
}

print $result;

这个案例2

my $test = 'abcd';
my $result;

for ($test) {
    /ad/ && do { $result = 'case 1'; last };
    /bc/ && do { $result = 'case 2'; last };
    /cd/ && do { $result = 'case 3'; last };
}

print $result;

默认

my $test = 'abcd';
my $result;

for ($test) {
    /aa/ && do { $result = 'case 1'; last };
    /bb/ && do { $result = 'case 2'; last };
    /cc/ && do { $result = 'case 3'; last };

    $result = 'Default';
}

print $result;

答案 6 :(得分:1)

假设您正在使用use Switch,则可以使用else子句

答案 7 :(得分:1)

如果您只需要决定作业,请使用三元运算符?:

die "Expecting name of the system (reise/synpac/vias) as parameter.\n"
    unless $_ = shift;
@opt{qw/Name Code Id UID/} =
    /^\s*rei(?:se)?\s*$/i   ? qw/ CEP    REI    80 ipcp_rei / :
    /^\s*syn(?:pac)?\s*$/i  ? qw/ SYNPAC SYNPAC 67 ipcp_sym / :
    /^\s*vias?\s*$/i        ? qw/ VIAS   VIAS   68 ipcp_via / :
    do { die "Unknown system ‘$_’.\n"; };   # or default values

答案 8 :(得分:0)

我编写并使用这三个Perl子程序开关,发现它们非常有用。

sub switchOne($){          # standard switch
my($prefix,$testVal,@caseVals)=@_;
$s=0;
    while($s<scalar(@caseVals)){
        if($testVal eq $caseVals->[$s]){
            return $prefix."_".$testVal;
        }
        $s++;
    }
return $prefix."Not";
}

sub switchTwo($){         # test for 2 conditions switch = mapping x & Y
my($prefix,$testVal1,$testVal2,@caseVals1,@caseVals2)=@_;
$s=0;
    while($s<scalar(@caseVals)){
        if($testVal1 eq $caseVals1->[$s] && $testVal2 eq $caseVals2->[$s]){
            return $prefix."_".$testVal1;
        }
        $s++;
    }
return $prefix."Not";
}

sub switchRange($){         # test for range switch
my($prefix,$testVal1,@caseVals1,@caseVals2)=@_;
$s=0;
    while($s<scalar(@caseVals)){
        if($testVal > $caseVals->[$s]&&$testVal < $caseVals2->[$s]){
            return $prefix."_".($s+1);
        }
        $s++;
    }
return $prefix."Not";
}


#############  here is the calling code 
$prefix="case";
@cases=(1,12,3,45,5,61,7,8,9,10);       # cases to test against / quote strings
$case=&switchOne($prefix,$testvariable,\@cases);  

# prefix must be different for each switch call for different labels
#duplicate labels can cause problems

while($case ne ""){
    # initialization common code block

    goto $case;

case_1:                #   cases in array
    #code
    last;

case_12:
     # code
     last;


case_61:
    last;
case_7:
    last;    
case_8:
    last;
case_9:
    last;
case_10:
    last;

caseNot:
     # no match comes here

     #code
     last;
}

#  here is a dbl variable matching call example
# prefix can be in the call quoted
# both cases must be true to get a match

$case=&switchTwo("intrsctn",$test1,$test2,\@cases1,\@cases2);
while($case ne ""){
    # initial code as desired
    goto $case;

intrsctn_1:  
     # code
     last;

# as many labels as cases

intrsctnNot:
    last;
}

# here is a switch example to test for a variable in a range (between)

$case=&switchRange("thscase",$testvariable,\@cases1,\@cases2);
while($case ne ""){

        goto $case;

thscase_1:       # this returns the array index +1 on the prefix
     # code
     last;

# as many labels as cases

thscaseNot:
    # N must be uppercase
    last;
}

答案 9 :(得分:0)

不需要功能

perlcritic 安全。从 else-if 链转换后,我将其与 20 多个选项一起使用。

my $key = 'fruity';  # User chosen value
my %code_ref = (
    apple => sub { print("Apple\n"); },
    pear => sub { my_other_code(); },
    orange => sub { my_still_other_code();  },
);
if ( exists $code_ref{$key} ) {
    $code_ref{$key}->();
}
else { # Default case
    print STDERR "$0: unknown option '$key'\n";
}