Break sur le cas par défaut dans le commutateur

88

Je suis un peu perplexe quand ou non à inclure breakaprès le dernier cas, souvent default.

switch (type) {
    case 'product':

        // Do behavior

        break;
    default:

        // Do default behavior

        break; // Is it considered to be needed?
}

breakJe crois comprendre que le seul but est d’empêcher le code de traverser le reste de la switchcasse.

Est-il alors considéré comme plus logique d’avoir un breakdernier pour des raisons de cohérence ou d’éviter de l’avoir du fait de son breaknon-utilisation fonctionnelle? Les deux sont logiques de différentes manières à mon avis.

Cela pourrait être comparé dans une certaine mesure à la fin d'un .phpfichier ?>. Je ne termine jamais avec ?>principalement en raison du risque de sortie d'espaces vides, mais on pourrait argumenter que ce serait la chose logique à la fin du fichier.

Robin Castlin
la source

Réponses:

144

breakn'est pas techniquement nécessaire après la dernière alternative (ce qui, notez-vous, ne doit pas l'être default: c'est parfaitement légal, et parfois même utile de mettre la defaultbranche en premier); Que votre code tombe à la fin de l' switchinstruction ou breaksà la fin de sa dernière branche a le même résultat.

Cependant, je terminerais toujours chaque branche, y compris la dernière, par un returnou break, pour trois raisons:

  1. Refactorability. Si toutes vos branches se terminent par breakou return, vous pouvez les réorganiser sans en changer le sens. Cela rend moins probable qu'une telle réorganisation introduise une régression.
  2. Cohérence et moindre surprise. La cohérence dit que vos branches doivent se terminer de manière cohérente, sauf si leur signification est réellement différente. Le principe de la moindre surprise veut que des choses similaires se ressemblent. La fin de la dernière branche d'un switchbloc exactement comme les précédentes remplit les deux, ce qui facilite la lecture et la compréhension. Si vous laissez de côté le contenu explicite break, la dernière branche sera optiquement différente (ce qui est particulièrement important pour une analyse rapide), et afin de voir que ce n'est pas vraiment différent, le lecteur doit descendre au niveau de la lecture des déclarations individuelles. .
  3. Se protéger. Si vous prenez l'habitude de fermer toutes vos switchbranches avec un break, cela deviendra automatique au bout d'un moment et vous aurez moins de chances de l'oublier accidentellement là où ça compte. En vous entraînant à attendre la breakfin de chaque branche, vous pourrez également détecter les breakinstructions manquantes , ce qui est excellent pour le débogage et le dépannage.
tdammers
la source
Merci pour votre perspicacité! Est-ce que breakdernier cas aswell :)
Robin Castlin
7
En C #, break(ou une autre instruction de flux de contrôle qui quitte le case) est techniquement nécessaire après la dernière alternative.
dan04
3
@ dan04: oui, bon point. C # est une exception ici, et c'est probablement parce que les concepteurs de switchlangages étaient au courant des problèmes de retombée dans les langues existantes et voulaient les prévenir. Les règles imposées par C # correspondent à peu près aux recommandations de ma réponse.
tdammers
De quelle langue parlez-vous spécifiquement? C? C ++? C #? Java? PHP?
svick
2
Un bon compilateur traiterait la finale breakcomme un NO-OP au lieu de générer une jmpinstruction à la prochaine, correct?
Nathan Osman
11

Étant donné l’ambiguïté qui existe autour de l’utilisation de switch-casedans la plupart des langues, lors de son utilisation, je suggérerais de toujours utiliser une breakdéclaration, sauf si elle est explicitement et par définition non voulue .

Ceci est en partie dû au fait que chaque caseappel est identique, ce qui, à mon avis, améliorerait la lisibilité. Mais cela signifie aussi que si quelqu'un (même vous) choisit d'insérer un caseaprès le dernier à un stade ultérieur, il n'a pas besoin de se préoccuper de vérifier le bloc précédent, ce qui pourrait aider à réduire les bugs lors de l'ajout de nouveau code.


la source
7
Quand je veux qu'un cas tombe à travers le suivant (et ce n'est pas le cas dégénéré case foo: case bar: ...), je mets un commentaire explicite dans le sens où je veux que la chute se produise. Le rend beaucoup plus clair.
Donal Fellows
3
Oui comme un simple commentaire // no breakà la place debreak;
Pacerier
Ou un [[fallthrough]]attribut en cas de C ++.
Ruslan
1

Il n'y a pas breaknécessaire après le dernier cas. J'utilise le mot " dernier " (pas par défaut ) car ce n'est pas nécessaire, par défaut le cas est le dernier.

switch(x)
{
case 1:
//do stuff
break;

default:
//do default work
break;

case 3:
//do stuff

}

Et nous savons, a break est nécessaire entre deux cases consécutifs . Parfois, j'utilise if(a!=0)dans mon code pour plus de lisibilité lorsque d'autres se réfèrent à mon code. Je peux choisir d'utiliser if(a), ce serait une question de mon choix

Suvarna Pattayil
la source
5
Pour moi, cela signifierait une "pause toujours utilisée", juste au cas où un programmeur ajouterait un nouveau caseà la fin de la votre switchsans vérifier qu'il breakexistait bien (ce serait la faute de ce programmeur, mais il vaut mieux être prudent, pour une raison quelconque, parce que vous pourriez être ce programmeur dans 6 mois-)
SJuan76
@ SJuan76 Oui, je suis d'accord, mieux vaut prévenir que guérir, si vous voulez garder une sauvegarde des erreurs futures, vous devez en inclure une à la fin.
Suvarna Pattayil
1
Avec cet argument en tête, vous pouvez également argumenter de toujours avoir , à la fin des tableaux au cas où une nouvelle valeur est insérée. Cependant, cela casse certains codes et a généralement l’air moche :)
Robin Castlin le
1
@Robin Mettre une virgule est différent. Si ce n'est pas le cas et que quelqu'un ajoute une nouvelle valeur à un tableau, il obtiendra une erreur de compilation. Cependant, il n'y aura pas d'erreur de compilation si l'instruction de cas précédente manque une pause - il serait donc possible qu'elle soit manquée et cause des erreurs d'exécution.
Keith Miller
@RobinCastlin Si le langage vous permettait de mettre un ,. Incase, a defaultété conçu pour être le dernier cas. Peut-être que la langue considérerait un breakaprès comme une erreur. En supposant qu’il breakétait permis de différencier UNIQUEMENT deux cas.
Suvarna Pattayil