Perl Switch Заявление - PullRequest
       57

Perl Switch Заявление

14 голосов
/ 07 февраля 2011

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

switch($a) {

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

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

Ответы [ 9 ]

35 голосов
/ 07 февраля 2011

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

use feature qw(switch);

given($a){
  when(1) { print 'Number one'; }
  when(2) { print 'Number two'; }
  default { print 'Everything else' }
}
11 голосов
/ 07 февраля 2011

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

use feature qw(switch);

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

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

6 голосов
/ 05 октября 2015

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

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 голосов
/ 07 февраля 2011

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

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

Выше будет выводить «other» для $n=3 и «one» для $n=1.

3 голосов
/ 15 января 2016

Этот оператор возвращает Случай 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;
3 голосов
/ 07 февраля 2011

«иначе это не то, что я ищу, поскольку это относится только к последнему блоку регистра».

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

use Switch 'fallthrough';

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

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

1 голос
/ 28 января 2015

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

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
1 голос
/ 07 февраля 2011

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

0 голосов
/ 20 декабря 2017

Я написал и использую эти три переключателя подпрограмм 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;
}
...