Cas de commutation Java: avec ou sans accolades?

85

Considérez les deux extraits de code suivants, avec des accolades:

switch (var) {
  case FOO: {
    x = x + 1;
    break;
  }

  case BAR: {
    y = y + 1;
    break;
  }
}

Sans accolades:

switch (var) {
  case FOO:
    x = x + 1;
    break;

  case BAR:
    y = y + 1;
    break;
}

Je sais que, dans l'extrait avec accolades, une nouvelle portée est créée en entourant chaque cas entre accolades. Cependant, si chaque cas n'a pas besoin de la nouvelle portée (c'est-à-dire qu'aucun nom de variable n'est réutilisé), y a-t-il une sorte de pénalité de performance pour l'utilisation des accolades avec une casse?

cdmckay
la source

Réponses:

99

y a-t-il une sorte de pénalité de performance pour l'utilisation des accolades avec un boîtier?

Aucun.

Les accolades sont là pour aider le compilateur à comprendre la portée d'une variable, d'une condition, d'une déclaration de fonction, etc. Cela n'affecte pas les performances d'exécution une fois que le code est compilé dans un exécutable.

MrValdez
la source
21

Aucune pénalité de performance du point de vue de l'exécution.

Légère pénalité des performances du point de vue de la compilation car il y a plus à analyser, mais si quelqu'un était vraiment préoccupé par cela, il devrait écrire son code sur une seule ligne :-)

Et maintenant pour la partie opinion de notre article ... Je mets toujours les {et} car il y a une pénalité pour la maintenabilité en ce que vous devrez probablement les mettre plus tard, et cela peut être pénible de les mettre plus tard ... mais c'est 103% de préférence personnelle.

TofuBière
la source
Je suis un peu curieux car je ne vois pas la réponse moi-même ... @TofuBeer, quand devez-vous ajouter les accolades? De plus, je suis totalement d'accord avec le point de maintenabilité, je ne vois tout simplement pas le problème de maintenabilité ATM. EDIT: tant pis. Je viens de lire le reste des réponses ci-dessous.
nyaray
Vous le faites en C ++ dans certains cas, donc si vous travaillez dans les deux langages, ce n'est pas une mauvaise habitude de prendre l'un ou l'autre.
TofuBeer
13

Comme nous le savons, les accolades pour les boîtiers de commutation ne sont pas nécessaires. L'utilisation d'accolades peut entraîner une confusion sur la portée d'un cas.

Une accolade ouvrante est généralement associée à quelque chose de significatif comme le début d'une fonction ou le début d'une boucle ou le début de la déclaration de classe ou le début de l'initialisation du tableau etc ... Nous savons qu'un cas sort du bloc switch lorsqu'il rencontre une rupture déclaration. Ainsi, l'utilisation d'accolades semble impliquer l'idée d'une portée différente pour un lecteur ignorant. Il est donc préférable d'éviter d'utiliser des accolades pour une meilleure lisibilité de la programmation.

ie quand j'ai quelque chose comme,

switch(i)
{
  case 1 :
  {
     //do something
  }
  System.out.println("Hello from 1");

  case 2: 
  ....
}

"Hello from 1" est imprimé. Mais l'utilisation d'accolades peut suggérer à un lecteur ignorant que le cas se termine par '}', sachant déjà ce que signifient généralement les accolades en cas de boucles, de méthodes, etc.

Comme nous avons des instructions jump-to-label en 'C', le contrôle passe simplement à la casse et continue son exécution. Donc, avec cette compréhension, c'est juste une mauvaise pratique d'utiliser des accolades lors de l'écriture de cas pour switch.

Techniquement parlant, vous pouvez entourer n'importe quel bloc de votre code avec une paire supplémentaire d'accolades lorsqu'il est utilisé avec une syntaxe valide. Utiliser des accolades dans le commutateur me semble au moins si mauvais que cela semble donner une sensation différente, comme je l'ai dit ci-dessus.

Ma suggestion: évitez simplement d'utiliser des accolades environnantes pour les boîtiers de commutation.

Vraiment rouge.
la source
5
Pas d'accord avec cela. Utiliser des accolades ET écrire du code en dehors des accolades serait une très mauvaise forme, oui, mais cela ne discrédite pas l'utilisation d'accolades en soi.
Max Roncace
12

Avec des accolades.

Il y a tellement de choses qui peuvent mal tourner avec les instructions switch que j'essaye de les éviter là où je peux, ie

  1. Oublier les pauses et donc avoir des retombées
  2. Oublier un cas par défaut et donc ne pas attraper une condition non prise en charge
  3. Réutiliser accidentellement des variables entre des instructions case, ou pire encore, affecter une variable qui EST partageant une variable entre des instructions case.

L'utilisation d'accolades est un moyen d'empêcher le partage intentionnel et accidentel de variables entre les instructions de cas

jklp
la source
8
L'inclusion des points 1 et 2 était trompeuse pour cette question (pour moi); votre ligne de fermeture devrait explicitement dire que les accolades résout 3 seulement - je pensais que vous vouliez dire que les accolades excluaient le besoin de pauses, puis j'ai essayé.
ataulm
Le point 3 n'a même pas de sens. Vous ne pouvez pas réutiliser des variables à moins qu'elles n'aient été déclarées dans une portée parente de l'instruction switch. Cela signifie que si vous déclarez une variable dans une case, elle ne peut pas être utilisée dans une autre instruction case. Si vous déclarez une variable au-dessus de l'instruction switch (dans la portée parent), peu importe si vous utilisez des accolades ou non, les instructions case auront accès à la variable.
dsingleton
Je viens de (re) découvrir que les variables déclarées dans le cas 1 peuvent toujours être dans la portée dans le cas 2. Ex: ...case 1: int a = 10; break; case 2: int a = 11; break; ...ne compile pas. (testé avec Oracle JDK 8)
anuragw
5

Cette question va probablement être fermée comme "argumentative" (BRACE WAR!) Mais que diable. J'aime vraiment les accolades après les étuis. Pour moi, cela fait que la vilaine syntaxe de commutateur ressemble plus au reste des constructions de langage. (Il n'y a pas de pénalité pour l'utilisation d'accolades dans ce "cas")

Andy White
la source
Je suppose que c'est une sorte de question objective ... Je retire l'argumentation
Andy White
Je préfère sans les accolades ... Je trouve que les accolades ajoutent beaucoup de bruit inutile.
cdmckay
Ouais, j'aimerais que ce soit plus comme ça: case (FOO) {x = x + 1} case (BAR) {y = y + 1}
Andy White
Espace blanc sensible == sympa. Accolades inutiles == sucer.
Shog9
3
whitespace == mélange d'onglets et d'espaces == suck (je pensais juste que je jetterais un commentaire tab vs space dans le mix)
Andy White
5

Vous dites que les accolades peuvent être omises car aucun nom de variable n'est réutilisé. En réutilisant les noms de variables, je suppose que vous entendez déclarer une nouvelle variable du même type.

Les accolades sont en fait les plus utiles pour vous assurer que vous ne finirez pas par réutiliser la même variable dans différents cases par erreur. Ils ne déclarent aucune variable aujourd'hui, mais quelqu'un les ajoutera demain et sans les accolades, le code est sujet aux erreurs.

Variable misérable
la source
3

Je n'utiliserais pas d'accolades pour les boîtiers de commutation.

  • L'instruction switch semble déjà assez baroque sans accolades.

  • Les boîtiers de commutation doivent être très courts. Lorsque vous devez déclarer des variables, c'est le signe que vous vous trompez.

Maintenant, passons au maintien d'un code C hérité qui utilise des boîtiers de plus de 500 lignes ...

starblue
la source
1

Je n'y ai jamais pensé auparavant. Je n'ai jamais eu besoin des accolades dans une clause case, donc je ne vois pas vraiment pourquoi vous en auriez besoin. Personnellement, je ne suis pas pour l'idée "Ce sera plus facile à maintenir", ce n'est que des ordures, ce sera plus facile à maintenir si le code a du sens et est documenté.

Pas d'accolades ... moins de syntaxe c'est plus

Gareth Davis
la source
les {et} font cependant ressortir les choses, ce qui facilite la lecture (IMO).
TofuBeer
Ouaip. J'allais partager l'histoire d'une méthode que j'ai dû modifier une fois (il m'a fallu environ 4 heures pour ajouter une ligne de code) mais le code était insensé (environ 10 pages de long et 4 pages de large une fois imprimé) donc ce n'est pas le cas typique. Mais s'il avait utilisé {}, il aurait fallu une minute pour l'ajouter.
TofuBeer
Je pense que le point est ici que si le programmeur d'origine s'était efforcé de mettre des blocs {} afin que le code soit plus lisible, il se serait peut-être soucié d'écrire une instruction de commutation de 10 pages et de changer le code pour être un peu moins fou
Gareth Davis
swtich aurait été un rêve ... il était imbriqué si / elses ... écrit en code C ++ par des programmeurs COBOL ... J'ai arrêté peu de temps après.
TofuBeer