Casos de troca de Java: com ou sem chaves?

86

Considere os dois snippets a seguir, com colchetes:

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

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

Sem colchetes:

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

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

Eu sei que, no snippet com colchetes, um novo escopo é criado colocando cada caso entre colchetes. No entanto, se cada caso não precisar do novo escopo (ou seja, nenhum nome de variável está sendo reutilizado), há algum tipo de penalidade de desempenho por usar as chaves com um caso?

cdmckay
fonte

Respostas:

100

existe algum tipo de penalidade de desempenho por usar o aparelho com um case?

Nenhum.

As chaves existem para ajudar o compilador a descobrir o escopo de uma variável, condição, declaração de função, etc. Ela não afeta o desempenho do tempo de execução uma vez que o código é compilado em um executável.

MrValdez
fonte
21

Sem penalidade de desempenho do ponto de vista da execução.

Uma pequena penalidade de desempenho do ponto de vista da compilação, pois há mais para analisar, mas se alguém estivesse realmente tão preocupado com isso, teria que escrever seu código todo em uma linha :-)

E agora, a parte da opinião de nossa postagem ... Eu sempre coloco o {e} porque há uma penalidade para a manutenibilidade em que você provavelmente terá que colocá-los em uma data posterior, e pode ser uma dor colocá-los mais tarde ... mas isso é 103% da preferência pessoal.

TofuBeer
fonte
Estou um pouco curioso, pois não consigo ver a resposta sozinho ... @TofuBeer, quando você TEM que adicionar o aparelho? Além disso, concordo totalmente com o ponto de manutenção, mas não vejo o problema de manutenção do ATM. EDIT: deixa pra lá. Acabei de ler o resto das respostas abaixo.
nyaray
Você faz em C ++ em alguns casos, então se você trabalha em ambas as linguagens, não é um mau hábito entrar em qualquer uma delas.
TofuBeer de
13

Como sabemos, chaves para casos de switch não são necessárias. O uso de casos de colchetes pode causar confusão sobre o escopo de um caso.

Uma chave de abertura é geralmente associada a algo significativo como o início de uma função ou início de um loop ou início de declaração de classe ou início de inicialização de array, etc ... Sabemos que, um caso quebras de bloco de switch quando encontra uma quebra declaração. Assim, o uso de colchetes parece sugerir a ideia de um escopo diferente para o caso para um leitor ignorante. Portanto, é melhor evitar o uso de chaves para melhorar a legibilidade da programação.

ou seja, quando eu tenho algo como,

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

  case 2: 
  ....
}

"Hello from 1" é impresso. Mas o uso de chaves pode sugerir a um leitor ignorante que o caso termina com '}', já sabendo o que as chaves geralmente significam no caso de loops, métodos etc.

Como temos instruções jump-to-label em 'C', o controle apenas muda para case e continua sua execução. Então, com esse entendimento, é apenas uma prática RUIM usar chaves ao escrever casos para switch.

Tecnicamente falando, você pode cercar qualquer bloco de seu código com um par adicional de chaves quando usado com sintaxe válida. Usar chaves no switch parece tão ruim, pelo menos para mim, pois parece dar uma sensação diferente como eu disse acima.

Minha sugestão: apenas evite usar chaves circundantes para casos de switch.

Vermelho real.
fonte
5
Discordo disso. Usar colchetes E escrever código fora dos colchetes seria muito ruim, sim, mas isso não desacredita o uso de colchetes em si.
Max Roncace
As chaves existem para prevenir exatamente a situação que você mencionou no seu exemplo ...
Petr Dvořák
12

Com aparelho.

Há tantas coisas que podem dar errado com as declarações switch que tento evitá-las sempre que posso, ou seja,

  1. Esquecer quebras e, portanto, ter quedas de caixa
  2. Esquecer um caso padrão e, assim, não pegar uma condição não atendida
  3. Reutilizar acidentalmente variáveis ​​entre declarações de caso, ou pior ainda, afetando uma variável que ESTÁ compartilhando uma variável entre declarações de caso.

O uso de chaves é uma maneira de evitar o compartilhamento intencional e acidental de variáveis ​​entre as declarações de caso

jklp
fonte
9
Incluir os pontos 1 e 2 foi enganoso para esta questão (para mim); sua linha de fechamento deve dizer explicitamente que os colchetes resolvem apenas 3 - pensei que você quisesse dizer que os colchetes excluíam a necessidade de quebras, então tentei.
ataulm
O ponto 3 nem mesmo faz sentido. Você não pode reutilizar variáveis ​​a menos que elas tenham sido declaradas em um escopo pai da instrução switch. Isso significa que se você declarar uma variável dentro de um caso, ela não poderá ser usada em outra instrução de caso. Se você declarar uma variável acima da instrução switch (no escopo pai), não importa se você usa colchetes ou não, as instruções case terão acesso à variável.
dsingleton 01 de
Acabei de (re) descobrir que as variáveis ​​declaradas no caso 1 ainda podem estar no escopo no caso 2. Ex: ...case 1: int a = 10; break; case 2: int a = 11; break; ...não compila. (testado com Oracle JDK 8)
anuragw
5

Esta questão provavelmente será encerrada como "argumentativa" (BRACE WAR!), Mas que diabos. Na verdade, gosto do aparelho depois dos casos. Para mim, isso faz com que a sintaxe feia do switch pareça mais com o resto das construções da linguagem. (Não há penalidade pelo uso de colchetes neste "caso")

Andy White
fonte
Acho que é uma questão objetiva ... Retiro a coisa argumentativa
Andy White
Eu prefiro sem o aparelho ... Acho que o aparelho adiciona muito ruído desnecessário.
cdmckay
Sim, gostaria que fosse mais assim: case (FOO) {x = x + 1} case (BAR) {y = y + 1}
Andy White,
Espaço em branco sensível == bom. Chaves desnecessárias == sugam.
Shog9
3
espaço em branco == mistura de tabulações e espaços == péssimo (apenas pensei em adicionar um comentário de tabulação vs. espaço na mistura)
Andy White
5

Você diz que as chaves podem ser omitidas porque nenhum nome de variável está sendo reutilizado. Ao reutilizar nomes de variáveis, suponho que você queira declarar uma nova variável do mesmo tipo.

As chaves são realmente mais úteis para garantir que você não reutilize a mesma variável em diferentes cases por engano. Eles não declaram nenhuma variável hoje, mas alguém as adicionará amanhã e sem as chaves o código está sujeito a erros.

Variável miserável
fonte
3

Eu não usaria aparelho para trocar casos.

  • A instrução switch parece bastante barroca já sem chaves.

  • Os casos de troca devem ser muito curtos. Quando você precisa declarar variáveis, é um sinal de que você está fazendo isso errado.

Agora vamos manter algum código C legado que permite trocar casos de mais de 500 linhas ...

azul da estrela
fonte
1

Nunca pensei nisso antes. Nunca precisei dos colchetes em uma cláusula case, então não posso realmente ver por que você precisaria deles. Pessoalmente, não acredito na ideia de "Será mais fácil de manter", isso é uma besteira, será mais fácil de manter se o código fizer sentido e estiver documentado.

Sem colchetes ... menos sintaxe é mais

Gareth Davis
fonte
o {e} faz as coisas se destacarem também, o que torna mais fácil de ler (IMO).
TofuBeer
Sim. Eu ia compartilhar a história de um método que uma vez tive que modificar (levei cerca de 4 horas para adicionar uma linha de código), mas o código era insano (cerca de 10 páginas de comprimento e 4 páginas de largura quando impresso), então não é o caso típico. Mas se tivesse usado {}, demoraria um minuto para adicioná-lo.
TofuBeer
Acho que o ponto é aqui que se o programador original tivesse feito o esforço de colocar {} blocos para que o código fosse mais legível, ele poderia realmente ter se importado em escrever uma instrução de troca de 10 páginas e alterar o código para ser um um pouco menos louco
Gareth Davis
swtich teria sido um sonho .. ele foi aninhado if / elses ... escrito em código C ++ por programadores COBOL ... Eu parei não muito tempo depois disso.
TofuBeer