Celui-ci vient d'arriver: Comment puis-je sortir d'une déclaration if
? J'ai une longue déclaration, mais il y a une situation où je peux m'échapper plus tôt.
En boucle, je peux faire ceci:
while (something ) {
last if $some_condition;
blah, blah, blah
...
}
Cependant, puis-je faire la même chose avec une déclaration if?
if ( some_condition ) {
blah, blah, blah
last if $some_other_condition; # No need to continue...
blah, blah, blah
...
}
Je sais que je pourrais mettre l'instruction if
à l'intérieur d'un bloc, puis sortir du bloc:
}
if ( some_condition ) {
...
last if $some_other_condition; # No need to continue...
blah, blah, blah
...
}
}
Ou, je peux créer un sous-programme (qui est probablement mieux par programme):
if ( some_condition ) {
run_subroutine();
}
sub run_subroutine {
blah, blah, blah
return if $some_other_condition;
blah, blah, blah
...
}
Mais est-il possible de sortir d'une condition if?
La question a été soulevée parce que j'aidais quelqu'un avec son code. Dans une instruction if
assez longue, plusieurs autres déclarations if
y étaient incorporées. Le code ressemblait à ceci:
if ( $condition1 ) {
blah, blah, blah;
if ( not $condition2 ) {
blah, blah, blah;
if ( not $condition3 ) {
blah, blah, blah;
}
}
}
Je pensais que tout pourrait être rendu plus lisible en faisant ceci:
if ( $condition1 ) {
last if $condition2;
blah, blah, blah;
last if $condition3;
blah, blah, blah;
}
Cela montre que le flux normal de l'instruction if
est standard, mais que, dans certaines conditions, l'instruction if
a été sortie tôt, ce qui revient à utiliser last
ou next
dans une boucle while
ou for
pour la sortir de la boucle.
J'ai aimé la solution de mpapec d'utiliser une étiquette - même si je n'utilise pas l'étiquette elle-même. L’étiquette est une description de ma if
:
IF-UNDER-CONDITION1:
{
if ( $condition1 ) {
last if $condition2;
blah, blah, blah;
last if $condition3;
blah, blah, blah;
}
}
Bien que ce ne soit pas une technique de codage standard, le flux de code est suffisamment évident pour qu'un développeur Perl de bas niveau (celui qui doit conserver ce code après mon départ) puisse comprendre ce que le code fait et le conserver. . Ils peuvent même apprendre quelque chose dans le processus.
Vous pouvez utiliser bloc de base qui est sujet à last
, next
et redo
, il y a donc une rupture possible.
if ($condition) {EXIT_IF:{
last EXIT_IF; # break from code block
print "never get's executed\n";
}}
EXIT_IF: {
if ($condition) {
last EXIT_IF; # break from code block
print "never get's executed\n";
}
}
Placez-le dans une boucle for()
vide et ajoutez last;
partout où vous souhaitez vous éclater ET après la if
. Un peu moche mais ça marche. Assurez-vous d'ajouter des commentaires pour expliquer l'astuce.
for (;;) {
if (condition) {
#code
last if another_condition;
}
last;
}
utilisez goto
et étiquetez une instruction après votre boucle pour cela. Être à jamais damné.
Bloc supplémentaire à l'intérieur de la if
(par exemple, if () {{ code }}
). Peut être difficile à lire pour les novices, mais OK si accompagné d’un commentaire.
votre propre solution: bloquer autour de if
. Pas très évident en lecture.
votre propre solution: sous-programme avec retour.
Franchement, à moins que le coût de l’appel d’un sous-chef n’ait plus d’importance, c’est la solution la plus propre en termes de lisibilité}.
Vous pouvez placer le reste de votre bloc if
dans une autre instruction if
, comme ceci:
if (some_condition) {
blah, blah, blah
if (!$some_other_condition) {
blah, blah, blah
...
}
}
J'ai tendance à utiliser des instructions if séquentielles basées sur "dois-je continuer?" variable à la place. Votre
if ( $condition1 ) {
blah, blah, blah;
if ( not $condition2 ) {
blah, blah, blah;
if ( not $condition3 ) {
blah, blah, blah;
}
}
}
peut être réorganisé à
my $ok = $condition1;
if ($ok) {
blah, blah, blah;
$ok = not $condition2;
}
if ($ok) {
blah, blah, blah;
$ok = not $condition3;
}
if ($ok) {
blah, blah, blah;
}
La réponse de DVK à jouer m'a inspirée et j'ai proposé cette variante qui fonctionne au moins sur Perl 5.26.1:
for( ; some_condition ; last ) {
blah, blah, blah
last if $some_other_condition; # No need to continue...
blah, blah, blah
}
Per perlsyn
, cela équivaut à:
while (some_condition) {
blah, blah, blah
last if $some_other_condition; # No need to continue...
blah, blah, blah
} continue {
last;
}
Dans un bloc continue
, last
a le même effet que s'il avait été exécuté dans la boucle principale. Par conséquent, la boucle s'exécutera zéro ou une fois, en fonction de some_condition
.
Perl -E 'my ($cond, $other)=(X, Y);
for(;$cond;last) { say "hello"; last if $other; say "goodbye" }'
a les résultats suivants, pour diverses valeurs X
et Y
:
X Y Prints
-----------------------
0 0 (nothing)
0 1 (nothing)
1 0 hello, goodbye
1 1 hello
Une autre alternative consiste à utiliser un sous-programme anonyme.
Remarque: Je ne recommande pas cette méthode en raison de la complexité supplémentaire de la portée (voir la remarque ci-dessous); c'est juste pour l'exhaustivité des réponses possibles.
if( $true_condition ){
(sub{
return if $true_condition;
...
})->();
}
Remarque: toute variable déclarée avec la routine doit utiliser our
au lieu de my
si vous souhaitez les utiliser dans le reste du code.
Conservez votre boucle while
pour pouvoir utiliser last
mais aussi en vous assurant que la boucle est exécutée au plus une fois.
my $loop_once = 1;
while ( $loop_once-- and some_condition ) {
blah, blah, blah
last if $some_other_condition; # No need to continue...
blah, blah, blah
...
}