Existe-t-il un moyen d'exécuter un bloc de code si aucun des blocs de cas ne correspond? Par exemple:
switch($a) {
case // {}
case // {}
...
# DO SOMETHING IF NONE OF THE ABOVE CASES WERE MATCHED
}
else
n'est pas ce que je recherche, car il s'applique uniquement au dernier bloc de cas.
Il y a toujours la commutation dans Perl 5.10, si vous l'exécutez bien sûr.
use feature qw(switch);
given($a){
when(1) { print 'Number one'; }
when(2) { print 'Number two'; }
default { print 'Everything else' }
}
Veuillez noter que use Switch
sous n'importe quelle forme est obsolète car il est remplacé (et supprimé dans la prochaine version de Perl) par la propre forme d'instruction switch de Perl, qui est, comme déjà répondu:
use feature qw(switch);
given ($x)
{
when ('case1') { print 1; }
default {print 0; }
}
L'utilisation de la casse par défaut permet d'obtenir le résultat souhaité. N'oubliez pas non plus d'utiliser last
si vous voulez que le commutateur cesse d'être évalué après qu'une condition est évaluée vraie.
J'utilise généralement la construction de bloc ci-dessous qui est plus simple et n'a pas besoin d'importer quoi que ce soit.
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;
else
est en effet ce que vous recherchez.
switch ( $n ) {
case 1 { print "one\n" }
case 2 { print "two\n" }
else { print "other\n" }
}
Ce qui précède afficherait "autre" pour $n=3
et "un" pour $n=1
.
Cette déclaration renvoie Cas 2:
my $test = 'abcd';
print test($test);
sub test {
for ($_[0]) {
/ad/ && return 'Case 1';
/bc/ && return 'Case 2';
/c/ && return 'Case 3';
}
}
Celui-ci retourne Cas:
my $test = 'abcd';
my $result;
for ($test) {
/ad/ && do { $result = 'case 1' };
/bb/ && do { $result = 'case 2' };
/cd/ && do { $result = 'case 3' };
}
print $result;
Celui-ci Cas 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;
par défaut:
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;
"Sinon, ce n'est pas ce que je recherche, car il ne s'applique qu'au dernier bloc de cas."
Tant que vous n'utilisez pas de transition:
use Switch 'fallthrough';
Tu es en sécurité.
Si vous atteignez la dernière instruction case, cela signifie qu'aucune des instructions case ci-dessus ne correspond aux critères. En d'autres termes (s'il n'y a pas d'interruption), l'instruction else n'est exécutée que si toutes les instructions case ne satisfont pas à leurs conditions.
Si vous avez seulement besoin de décider d'une affectation, utilisez l'opérateur ternaire ?:
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
En supposant que vous utilisez use Switch
, vous pouvez utiliser une clause else
J'ai écrit et utilisé ces trois commutateurs de sous-programmes Perl et je les trouve très utiles.
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;
}