Devrait instructions de commutation toujours contenir une clause de défaut?
Dans l'une de mes premières revues de code (un temps), on m'a dit que c'est une bonne pratique d'inclure une clause de défaut dans toutes les instructions switch. J'ai récemment souvenu de ce conseil mais ne peut pas se souvenir de la raison. Il semble assez étrange pour moi maintenant.
-
Est-il une raison logique pour toujours, y compris une instruction par défaut?
-
Est-ce dépendant d'une langue? Je ne me souviens pas quelle est la langue que j'utilisais à l'époque - peut-être que cela s'applique à certaines langues et pas à d'autres?
- Ça va être dépendantes de la langue, dans une large mesure
Vous devez vous connecter pour publier un commentaire.
Commutateur de cas devrait presque ont toujours une
default
cas.Raisons de l'utilisation d'un
default
1.Pour "attraper" une valeur inattendue
2. Pour gérer "par défaut" des actions, où c'est le cas pour un comportement particulier.
Vous voyez BEAUCOUP dans le menu programmes et scripts shell bash. Vous pouvez aussi le voir, quand une variable est déclarée en dehors de l'interrupteur de cas, mais pas initialisé, et chaque cas initialise à quelque chose de différent. Ici, le défaut doit initialiser trop de sorte que la ligne de code qui accède à la variable ne soulève pas une erreur.
3. Montrer à quelqu'un de lire votre code que vous avez couvert l'affaire.
C'était un exemple simplifié, mais le point est que quelqu'un qui lit le code ne doit pas se demander pourquoi
variable
ne peut pas être autre chose que 1 ou 2.Le seul cas que je peux penser à ne PAS utiliser
default
est lorsque le commutateur est en train de vérifier quelque chose où son assez évident tous les autres alternatives peuvent être joyeusement ignoréenum MyEnum { FOO = 0, BAR = 1 }; MyEnum value = (MyEnum)2;
rend valideMyEnum
instance qui n'est pas égal àFOO
ouBAR
. Si l'une de ces questions serait de provoquer une erreur dans votre projet, un cas de défaut va vous aider à trouver l'erreur très rapidement, souvent sans débogueur nécessaire!Pas.
Que faire si il n'y a aucune action par défaut, le contexte a son importance. Que faire si vous n'en avez que pour agir sur quelques valeurs?
Prendre l'exemple de la lecture des combinaisons de touches pour un jeu
Ajoutant:
Est juste un gaspillage de temps et augmente la complexité du code pour aucune raison.
// do nothing
commentaire précise qu'il est " ok " si tous les cas sont couverts, par opposition à d'autres instructions de commutation où ce serait 'pas ok'.actOnMovementKeystrokes
. Cela rend également clair que c'est ok si pas tous les cas sont couverts. Bonus: vous obtenez un les mieux conçus de classe...Je serais toujours utiliser une clause de défaut, quelle que soit la langue dans laquelle vous travaillez.
Les choses peuvent aller mal. Les valeurs ne seront pas ce que vous attendez, et ainsi de suite.
Ne pas vouloir inclure une clause de défaut implique que vous êtes certain que vous savez l'ensemble des valeurs possibles. Si vous pensez que vous connaissez l'ensemble des valeurs possibles ensuite, si la valeur est en dehors de cet ensemble de valeurs possibles, vous souhaitez être informés de il - c'est certainement une erreur.
C'est la raison pour laquelle vous devriez toujours utiliser une clause de défaut et de jeter une erreur, par exemple en Java:
Il n'y a aucune raison d'inclure davantage d'informations que la simple "inaccessible" de la chaîne; s'il se produit réellement, vous allez avoir besoin de regarder la source et les valeurs des variables etc de toute façon, et à l'exception stacktrace comprendra que le numéro de ligne, donc pas besoin de perdre votre temps à écrire plus de texte dans le message d'exception.
throw new RuntimeException("myVar invalid " + myVar);
car cela pourrait vous donner assez d'informations pour comprendre et résoudre le problème sans avoir à utiliser un débogueur et inspecter des variables, ce qui peut être difficile si c'est un plus rarement problème qui est difficile à reproduire.default:
. Mais, le plus souvent, on laisse un défaut car on pensemyVar
ne peut jamais avoir une valeur autre que celles énumérées; cependant je ne peux pas compter le nombre de fois où j'ai été surpris de voir dans la vie réelle lorsque la variable a une valeur autre que les valeurs qu'il "pourrait" avoir des. Dans ces cas, j'ai été heureux de l'exception en me faisant voir que dès le départ, plutôt que de provoquer une autre erreur plus tard (plus difficile à déboguer) ou de mauvaise réponse (obtenir négligé dans les essais).AssertionError
au lieu deRuntimeException
, que cette situation est très semblable à une affirmation indiquant quemyVar
est l'une des valeurs manipulées. De plus, les chances que quelqu'un l'attrape et avale l'erreur est plus petite.AssertionError
est une bonne idée, vous avez raison! Je suppose que vous avez raison sur la question des personnes potentiellement à avaler tous lesException
s, mais j'essaie de ne pas écrire du code avec de telles personnes 😉N'ayant PAS le cas par défaut peut être bénéfique dans certaines situations.
Si votre commutateur cas sont les énumérations, les valeurs, en n'ayant pas un cas de défaut, vous pouvez obtenir un message d'avertissement du compilateur si il vous manque l'un des cas. De cette façon, si de nouvelles valeurs enum sont ajoutés dans le futur et que vous oubliez d'ajouter des cas, pour ces valeurs dans le commutateur, vous pouvez vous renseigner sur le problème au moment de la compilation. Vous devriez toujours vous assurer que le code prend les mesures appropriées pour non gérée valeurs, dans le cas où une valeur non valide a été moulé pour le type enum. Donc, cela peut fonctionner mieux pour les cas simples où l'on peut revenir dans l'énumération de cas plutôt que de rompre.
Dans ma société, nous avons écrire des logiciels pour l'Avionique et Défense de marché, et nous avons toujours inclure une instruction par défaut, parce que TOUS les cas dans une instruction switch doit être explicitement traitées (même si c'est juste un commentaire en disant: 'Ne rien faire'). Nous ne pouvons nous permettre le logiciel juste pour se conduisent mal ou tout simplement de crash sur inattendue (ou même ce que nous pensons impossible) de valeurs.
Il peut être discutée qu'un cas de défaut n'est pas toujours nécessaire, mais toujours exigeant, il est facilement vérifié par nos analyseurs de code.
Si une instruction "switch" toujours inclure une clause de défaut? Pas de. Il devrait généralement comprennent un défaut.
Y compris une clause de défaut n'a de sens que si il ya quelque chose pour elle de le faire, comme faire valoir une condition d'erreur ou de fournir un comportement par défaut. Y compris un "juste parce que" est-cargo culte de la programmation et ne fournit aucune valeur. C'est le "switch" équivalent de dire que tous les "si" états devraient inclure un "else".
Voici un exemple trivial d'où il n'a pas de sens:
C'est l'équivalent de:
default:
dans ces cas codifie vos hypothèses. Par exemple, est-il OK lorsquesgn==0
pour imprimerinteger
(ni positif, ni négatif), ou est-ce une erreur? Pour moi la lecture de ce code, c'est difficile à dire. Je suppose que vous voulez écrirezero
dans ce cas ne pasinteger
, et que le programmeur fait l'hypothèse quesgn
ne peut être égal à -1 ou +1. Si c'était le cas, ayant lesdefault:
serait de permettre au programmeur d'attraper l'hypothèse de l'erreur de début et de modifier le code.Aussi loin que je le vois, la réponse est "par défaut" est facultative, en disant d'un interrupteur doit toujours contenir une valeur par défaut est comme de dire que tous les 'if-elseif' doit contenir un 'autre'.
Si il y a une logique à faire par défaut, la valeur "par défaut" déclaration devrait être là, mais sinon, le code pourrait poursuivre l'exécution sans rien faire.
Avoir une clause de défaut quand il n'est pas vraiment nécessaire est Une programmation défensive
Cela conduit généralement à un code qui est trop complexe à cause de trop de code de gestion d'erreur.
Cette gestion d'erreur et le code de détection de nuit à la lisibilité du code, rend la maintenance plus difficile et conduit à terme à plus de bugs qu'elle n'en résout.
Donc je crois que si le défaut ne devrait pas être atteint - vous n'avez pas à les ajouter.
Note que "ne devrait pas être atteint" signifie que s'il atteint c'est un bug dans le logiciel vous avez besoin pour tester les valeurs qui peuvent contenir des valeurs indésirables en raison de la saisie de l'utilisateur, etc.
Je dirais que cela dépend de la langue, mais en C si vous êtes à la commutation sur un type enum et vous gérer chaque valeur possible, vous êtes probablement mieux de ne PAS y compris un cas de défaut. De cette façon, si vous rajoutez une enum balise et d'oublier de l'ajouter à l'interrupteur, compétente compilateur vous donnera un avertissement de l'absence de cas.
gcc -Wall
(en quelque sorte le plus petit dénominateur commun compétente compilateurs) donne des avertissements sur les énumérations non gérée dans les instructions switch.Si vous savez que l'instruction switch n'aurez jamais un strict défini des étiquettes ou les valeurs, il suffit de faire ce pour couvrir les bases, de cette façon, vous obtiendrez toujours valide résultat.. il suffit de mettre la valeur par défaut sur le label par programme/logiquement être le meilleur gestionnaire pour d'autres valeurs.
default
encore ici? Ou ne faire cela permettra à certaines syntaxe particulière qui vous a permis de le supprimer?Au moins il n'est pas obligatoire en Java. Selon JLS, il dit atmost un cas par défaut peuvent être présents. Ce qui signifie qu'aucun cas de défaut est acceptable . À la fois dépend aussi du contexte que vous êtes à l'aide de l'instruction switch. Par exemple en Java, le commutateur suivant bloc ne nécessite pas de cas de défaut
Mais la méthode suivante qui n'attend que de retourner une Chaîne de caractères, cas par défaut est très utile pour éviter les erreurs de compilation
si vous pouvez éviter d'erreur de compilation pour la méthode ci-dessus, sans avoir par défaut au cas par juste d'avoir une instruction de retour à la fin, mais la prestation de cas par défaut le rend plus lisible.
Vous devriez avoir une valeur par défaut à attraper des nations unies-les valeurs attendues venir dans.
Cependant, je suis en désaccord avec le Adrian Smith que votre message d'erreur par défaut devrait être quelque chose de totalement dépourvue de sens. Il y a peut être un non-traitée cas où vous n'avez pas entrevoir (qui est un peu le but) que votre utilisateur peut voir et un message comme "inaccessible" est totalement inutile et n'aide pas n'importe qui dans cette situation.
Cas au point, combien de fois avez-vous eu un totalement dénuée de sens BSOD? Ou une exception fatale @ 0x352FBB3C32342?
Si la valeur du commutateur (switch(variable)) ne peut pas atteindre le cas par défaut, puis en cas de défaut n'est pas du tout nécessaire. Même si nous gardons le cas par défaut, il n'est pas exécuté. C'est du code mort.
C'est une option de codage de "convention". Selon l'usage est de savoir si ou non il est nécessaire. Personnellement, je crois que si vous n'en avez pas besoin, il ne devrait pas être là. Pourquoi inclure quelque chose qui ne sera pas utilisé, ou atteinte par l'utilisateur?
Si le cas les possibilités sont limitées (c'est à dire un Booléen), alors la clause de défaut est redondant!
Si il n'y a pas de cas par défaut dans un
switch
déclaration, le comportement peut être imprévisible, si ce casse pose à un moment donné du temps, ce qui n'était pas prévisible au stade de développement. C'est une bonne pratique
pour inclure un
default
cas.Une telle pratique peut entraîner un bug comme déréférencement de pointeur NUL, fuite de mémoire ainsi que d'autres types de
de sérieux bugs.
Pour l'exemple, nous supposons que chaque condition initialise un pointeur. Mais si
default
cas estcensé survenir et si nous n'avons pas l'initialiser dans ce cas, il y a toutes les possibilité de l'atterrissage jusqu'
avec une exception de pointeur null. Par conséquent, il est suggéré d'utiliser une
default
instruction du cas, même si ilpeut-être trivial.
Parce que MISRA C dit:
Cela dit, je recommande contre MISRA C sur ce, pour la plupart des logiciels:
Le cas par défaut ne peut pas nécessaires dans le commutateur utilisé par le protocole enum. lorsque le commutateur tous les contenus de valeur, le cas par défaut ne sera jamais exécuter. Donc dans ce cas, il n'est pas nécessaire.
Dépend de la façon dont le commutateur en particulier la langue des œuvres, mais dans la plupart des langues en aucun cas appariés, l'exécution passe à travers l'instruction switch sans avertissement. Imaginez-vous prévu un certain ensemble de valeurs et de prises en charge dans le commutateur, cependant, vous obtenez une autre valeur dans l'entrée. Rien ne se passe et vous ne savez rien de ce qui s'est passé. Si vous avez attrapé le cas par défaut, vous le savez, il y a quelque chose de mal.
Devrait instructions de commutation toujours contenir une clause de défaut ?
Pas d'interrupteur cas peut exister hors cas de défaut, commutateur cas de défaut cas de déclenchement de l'interrupteur de la valeur
switch(x)
dans ce cas x lorsque correspondent pas avec les autres cas de valeurs.Je crois que c'est tout à fait spécifiques à la langue et pour le C++ cas un point mineur pour enum class type. Ce qui semble plus sûr que les traditionnels C enum. MAIS
Si vous regardez à la mise en œuvre de std::byte c'est quelque chose comme:
Source: https://en.cppreference.com/w/cpp/language/enum
Et aussi pensez à ceci:
Source: https://en.cppreference.com/w/cpp/language/list_initialization
Ceci est un exemple de l'enum de classe représentant les valeurs qui ne sont pas définis à l'énumérateur. Pour cette raison, vous ne pouvez pas placer une confiance totale dans les énumérations. Selon l'application, ce qui pourrait être important.
Cependant, j'aime vraiment ce que @Harlan Kassler a dit dans son post et va commencer à utiliser cette stratégie dans certaines situations de moi-même.
Juste un exemple dangereux enum class: