Frequentemente, quando ouço sobre a declaração do switch, é adiada como uma maneira de substituir cadeias longas se ... else. Mas parece que quando eu uso a instrução switch, estou escrevendo mais código do que eu estaria escrevendo se ... mais. Você também tem outros problemas, como manter todas as variáveis para todas as chamadas no mesmo escopo .
Aqui está um código que representa o fluxo que eu normalmente escrevo ( graças ao diam )
String comment; // The generated insult.
int which = (int)(Math.random() * 3); // Result is 0, 1, or 2.
if (which == 0) {
comment = "You look so much better than usual.";
} else if (which == 1) {
comment = "Your work is up to its usual standards.";
} else if (which == 2) {
comment = "You're quite competent for so little experience.";
} else {
comment = "Oops -- something is wrong with this code.";
}
Então eles querem que eu substitua isso por isso:
String comment; // The generated insult.
int which = (int)(Math.random() * 3); // Result is 0, 1, or 2.
switch (which) {
case 0:
comment = "You look so much better than usual.";
break;
case 1:
comment = "Your work is up to its usual standards.";
break;
case 2:
comment = "You're quite competent for so little experience.";
break;
default:
comment = "Oops -- something is wrong with this code.";
}
Parece muito mais código em uma sintaxe muito mais estranha. Mas existe realmente uma vantagem em usar a instrução switch?
Respostas:
Para esta situação em particular, parece-me que são
if
ecase
são más escolhas. Eu usaria uma matriz simples:Como uma observação lateral, você geralmente calcula o multiplicador com base no tamanho da matriz, em vez de codificar
3
.Como para quando se usar um caso / interruptor, a diferença a partir de uma cascata de
if
declarações (ou, pelo menos, uma grande diferença) é queswitch
pode semi-automaticamente optimizar com base no número e densidade de valores, ao passo que uma cascata deif
declarações folhas do compilador com pouca opção a não ser gerar o código conforme você o escreveu, testando um valor após o outro até encontrar uma correspondência. Com apenas três casos reais, isso dificilmente é uma preocupação, mas com um número suficiente pode / pode ser significativo.fonte
case
declaração ou uma cascata deif
declarações adequadas. Na maioria das vezes, eles são um substituto (medíocre) para algum tipo de coisa de mapa / matriz, e é melhor você usar um desses diretamente.static const
matriz, para garantir que ela sempre existisse (mas nenhuma linguagem foi dada na pergunta, então tentei não assumir uma na resposta também). )O problema com a
if...else if...
cadeia é que, quando eu leio para ler, tenho que analisar todas asif
condições para entender o que o programa está fazendo. Por exemplo, você pode ter algo parecido com isto:(obviamente, para um pequeno número de declarações como essa, não é tão ruim)
Eu não teria como saber que você alterou a variável de condição no meio do caminho sem ler cada instrução. No entanto, como a
switch
limita a apenas uma variável de condição, posso ver rapidamente o que está acontecendo.No final do dia, porém, eu preferiria nem
switch
uma cadeia deif...else if
. Freqüentemente, uma solução melhor é algum tipo de tabela de salto ou dicionário para casos como na pergunta original ou polimorfismo (se o seu idioma suportar isso). Nem sempre é possível, é claro, mas eu procuraria uma solução que evite oswitch
primeiro passo ...fonte
A maneira acima de escrever esse tipo de caixa de mudança é bastante comum. A razão pela qual você sentiu a caixa de mudança se mais volumosa é porque seu corpo era apenas uma linha e, com uma caixa de troca, você também precisava da declaração de interrupção. Portanto, o gabinete do switch tinha o dobro do tamanho do corpo. Com um código mais substancial, a declaração de quebra não adicionará muito ao corpo. Para o corpo de linha única, é uma prática comum escrever o código na mesma linha que a instrução case.
Como outros já mencionaram, um caso de opção torna a intenção mais clara. Você deseja tomar uma decisão com base no valor de uma única variável / expressão. Meus comentários são puramente do ponto de vista da legibilidade e não são baseados em desempenho.
fonte
return
a seqüência correta em cada caso , poderá eliminar asbreak
instruções.Nesse caso, a instrução switch corresponde mais claramente à intenção do código: escolha uma ação a ser tomada com base em um único valor.
As declarações if, por outro lado, são muito mais difíceis de ler - você precisa examinar todas elas para ter certeza do que está acontecendo. Para mim, é menos código (mesmo se a contagem de caracteres pode ser um pouco maior), como há menos mentalmente analisar.
fonte
Eu concordo com Jerry que uma matriz de strings é melhor para esse caso em particular, mas que, em geral, é melhor usar uma instrução switch / case do que uma cadeia de elseifs. É mais fácil de ler e, às vezes, o compilador pode otimizar dessa maneira, mas também há outro benefício: é muito mais fácil depurar.
Quando você pressiona esse botão, você só precisa dar um passo para terminar no ramo direito, em vez de passar cuidadosamente por várias instruções if, uma de cada vez, e possivelmente pressionar a tecla muito rapidamente e passar por ela, perdendo alguma coisa e tendo Recomeçar.
fonte
Eu prefiro alternar nesses tipos de casos, ele corresponde muito melhor ao ponto do código, executa uma instrução diferente para cada valor de entrada diferente. Ele
if..else
age mais como um "truque" para obter o mesmo efeito.switch
declarações também são mais limpas, é fácil ocultar erros de digitação em todos==
Além disso, para grandes blocos em C, o switch é mais rápido.
else..if
pode ser mais apropriado quando você tem algo como intervalos (entre 1 e 100, faça isso, entre 100 e 200), ou em C, quando você tenta alternar com elementos como strings (isso é possível em outros idiomas). Qual é o mesmo.Costumo usar muitas opções quando programa em C.
fonte
Escolha algo que seja eficiente, conciso e depois documente não apenas o que você fez, mas por quê.
O código pode ser revisitado, e nem sempre por seu autor original.
Há momentos em que você pode escolher deliberadamente uma implementação em detrimento de outra, porque pensa em um código que não existe.
fonte
Eu geralmente não gosto de nenhuma das abordagens. Long switch ou if apenas imploram para serem refatorados para uma abstração orientada a objeto (no entanto, seu exemplo eu classificaria como curto, não longo).
Pessoalmente, envolvia esse tipo de código em um método auxiliar separado.
A colocação do switch em um método separado permite colocar instruções de retorno diretamente dentro da instrução switch (pelo menos em c #), eliminando a necessidade de instruções de interrupção, tornando o código muito mais fácil de ler.
E isso é muito melhor do que a abordagem if / else if / else if.
fonte
Em python, não há nenhuma instrução switch, porque se / elif / else é bom:
Simples né?
fonte
Elif
é apenas uma declaração if com algumas letras faltando. Definitivamente, é mais umaif
declaração do que uma declaração de troca. O fato de o Python NÃO ter uma opção faz com que quem os odeie (como eu) pense que não está sozinho.meta
menos que seja um tópico conhecido. Obrigado por me dar uma testemunha.Uma das coisas que torna o estilo C / C #
switch
particularmente irritante é a insistência em que ocase
valor seja literal. Uma coisa legal do VB / VB.NET é queselect/case
permite que cada caso seja qualquer expressão booleana. Isso é conveniente. Na medida em que uma série de expressões booleanas mutuamente exclusivas geralmente é útil, uma série de if / else ifs é mais flexível, além de ser mais eficiente para digitar e ler.fonte