2011-02-07 9 views
10

Czy istnieje sposób uruchomienia bloku kodu, jeśli żaden z bloków nie został dopasowany? Na przykład:Deklaracja przełącznika Perl

switch($a) { 

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

else nie jest to, czego szukam, ponieważ odnosi się tylko do ostatniego bloku case.

Odpowiedz

31

Zawsze jest przełączanie w Perlu 5.10, jeśli używasz go oczywiście.

use feature qw(switch); 

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

Pełna dokumentacja dotycząca funkcji przełącznika: http://perldoc.perl.org/perlsyn.html#Switch-statements – RickF

+0

muszą zawierać numer wersji w „użyciu” oświadczenie na podstawie składni chcesz, jak dobrze. – SMT

1

Zakładając, że używasz use Switch, można użyć else klauzuli

5

else jest rzeczywiście to, czego szukasz.

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

Powyższy byłoby wyjście "inne" na $n=3 i "jeden" dla $n=1.

3

„jeszcze nie jest to, czego szukam, ponieważ odnosi się tylko do ostatniego bloku case”.

Dopóki nie używasz spadek przezroczystości:

use Switch 'fallthrough'; 

Jesteś bezpieczny.

Jeśli dotrzesz do ostatniego przypadku, oznacza to, że żadna z powyższych instrukcji nie spełnia kryteriów. Innymi słowy (jeśli nie ma fall-through) instrukcja else jest wykonywana tylko wtedy, gdy wszystkie instrukcje case nie spełniają ich warunków.

10

Uwaga use Switch w jakiejkolwiek formie jest przestarzała, gdyż jest zastępowana (i usunięte w następnej wersji perla) przez Perl własnej postaci instrukcji switch, który jest, jak już odpowiedział:

use feature qw(switch); 

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

Używanie domyślnego przypadku osiąga pożądany rezultat. Nie zapomnij także użyć opcji last, jeśli chcesz, aby przełącznik przestał być oceniany po spełnieniu jednego warunku true.

+2

+1 dla wskazówki dotyczącej wycofania/usunięcia – daxim

+0

Należy zauważyć, że dany/kiedy został później uznany za eksperymentalny. Można oczywiście pozbyć się ostrzeżeń, dodając "brak ostrzeżeń" eksperymentalnych "; komunikat. Zobacz http://perldoc.perl.org/functions/given.html – Nagev

1

Jeśli trzeba tylko zdecydować zadanie użyć operatora trójskładnikowych ?:

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 
5

Zwykle używam poniższego bloku konstrukt, który jest bardziej proste i nie ma potrzeby importowania czegokolwiek.

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; 
0

Ten powrót oświadczenie Przypadek 2:

my $test = 'abcd'; 

print test($test); 

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

Ten powrót Przypadek 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; 

Ten Przypadek 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; 

Domyślnie:

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; 
0

pisałem i wykorzystać te trzy przełączniki Perl podprogramów i je znaleźć bardzo użyteczne.

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; 
}