Заявление о переходе на Perl

Есть ли способ запустить блок кода, если ни один из блоков case не был сопоставлен? Например:

switch($a) {

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

else не то, что я ищу, поскольку он применяется только к последнему блоку case.

Ответ 1

Всегда есть переход на Perl 5.10, если вы его запускаете, конечно.

use feature qw(switch);

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

Ответ 2

Обратите внимание, что use Switch в любой форме устарела, поскольку она заменяется (и удаляется в следующей версии perl) с помощью собственной формы оператора switch, которая уже отвечает:

use feature qw(switch);

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

Использование случая по умолчанию достигает желаемого результата. Также не забудьте использовать last, если вы хотите, чтобы переключатель переставал оцениваться после того, как одно условие оценивается как true.

Ответ 3

else действительно то, что вы ищете.

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

Вышеуказанное выведет "другое" для $n=3 и "one" для $n=1.

Ответ 4

Я обычно использую нижеследующую конструкцию блока, которая более проста и не нуждается в импорте.

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;

Ответ 5

"else - это не то, что я ищу, поскольку оно применимо только к последнему блоку case."

Пока вы не используете провал:

use Switch 'fallthrough';

Вы в безопасности.

Если вы достигнете последнего оператора case, это означает, что ни один из вышеприведенных описаний case не соответствует критериям. Другими словами (если нет провалов) оператор else выполняется только в том случае, если все case-запросы не удовлетворяют их условиям.

Ответ 6

Предполагая, что вы используете use Switch, вы можете использовать предложение else

Ответ 7

Если вам нужно только решить назначение, используйте тернарный оператор ?:

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

Этот оператор возвращает Случай 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;

Ответ 9

Я написал и использовал эти три подпрограммы Perl и нашел их очень полезными.

sub switchOne($){          # standard switch
my($prefix,$testVal,@caseVals)[email protected]_;
$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)[email protected]_;
$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)[email protected]_;
$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;
}