Interrupção no caso padrão no comutador


88

Estou um pouco confuso sobre quando ou não incluir breakapós o último caso, com frequência default.

switch (type) {
    case 'product':

        // Do behavior

        break;
    default:

        // Do default behavior

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

breakMeu único objetivo é, no meu entendimento, impedir que o código seja executado no restante da switchcaixa.

Considera-se então mais lógico ter um breakúltimo devido à consistência ou ignorar devido à breakaplicação de nenhum uso funcional? Ambos são lógicos de maneiras diferentes, na minha opinião.

Até certo ponto, isso pode ser comparado ao final de um .phparquivo ?>. Eu nunca termino ?>principalmente devido ao risco de gerar espaços em branco, mas pode-se argumentar que seria lógico finalizar o arquivo.

Respostas:


144

breaknão é tecnicamente necessário após a última alternativa (que, lembre-se, não precisa ser default: é perfeitamente legal e às vezes até útil colocar o defaultramo em primeiro lugar); se o seu código cai no final da switchinstrução ou breaksno final de sua última ramificação tem o mesmo resultado.

No entanto, eu ainda terminaria todas as ramificações, incluindo a última, com uma declaração returnou break, por três razões:

  1. Refatoração. Se todos os seus ramos terminarem com breakou return, você poderá reordená-los sem alterar o significado. Isso torna menos provável que essa reordenação introduza uma regressão.
  2. Consistência e menos surpresa. A consistência diz que seus ramos devem terminar de maneira consistente, a menos que tenham um significado diferente. O princípio da menor surpresa determina que coisas semelhantes devem parecer semelhantes. Terminar o último ramo de um switchbloco exatamente como os anteriores cumpre ambos, o que facilita a leitura e o entendimento. Se você deixar de fora o explícito break, o último ramo será opticamente diferente (o que é especialmente importante para uma varredura rápida) e, para ver que realmente não é diferente, o leitor precisará descer ao nível básico da leitura de declarações individuais .
  3. Se protegendo. Se você criar o hábito de terminar todos os seus switchramos com a break, ele se tornará automático depois de um tempo e será menos provável que você esqueça acidentalmente onde isso importa. Treinar-se para esperar o breakfinal de cada ramificação também ajuda a detectar breakinstruções ausentes , o que é ótimo para depuração e solução de problemas.

Obrigado pela sua compreensão! Vai breakdurar o caso também :)
Robin Castlin

7
Em C #, break(ou outra instrução de fluxo de controle que sai do case) é tecnicamente necessária após a última alternativa.
dan04

3
@ dan04: sim, bom ponto. O c # é uma exceção aqui, e provavelmente porque os designers de idiomas conheciam os problemas com falhas switchnos idiomas existentes e queriam evitá-los. As regras que o C # impõe praticamente correspondem às recomendações da minha resposta.
tdammers

De que idioma você está falando especificamente? C? C ++? C #? Java? PHP?
svick

2
Um bom compilador trataria o final breakcomo um NO-OP em vez de gerar um jmppara a próxima instrução, correto?
22613 Nathan Osman

11

Dada a ambiguidade existente em torno do uso de switch-casena maioria dos idiomas, ao usá-lo , sugiro sempre o uso de uma breakdeclaração, exceto quando explicitamente e por design não desejado .

Em parte, isso ocorre porque faz com que cada casechamada pareça a mesma, o que, na minha opinião, melhoraria a legibilidade. Mas também significa que se alguém (até você) optar por inserir um caseapós o último em um estágio posterior, não precisará se preocupar em verificar o bloco anterior, o que poderia ajudar a reduzir os erros ao adicionar novo código.


7
Quando eu quero que um caso caia para o próximo (e não é o caso degenerado de case foo: case bar: ...), coloquei um comentário explícito no sentido de que quero que o caso ocorra. Torna muito mais claro.
Donal Fellows

3
Sim, como um comentário simples // no breakno lugar debreak;
Pacerier

Ou um [[fallthrough]]atributo no caso de C ++.
Ruslan

1

Não é breaknecessário após o último caso. Eu uso a palavra " last " (não padrão ), porque não é necessário caso padrão é o último caso.

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

default:
//do default work
break;

case 3:
//do stuff

}

E nós sabemos, a break é necessário entre dois cases consecutivos . Às vezes, uso if(a!=0)no meu código para obter mais legibilidade quando outras pessoas fazem referência ao meu código. Eu posso optar por usar if(a), isso seria uma questão de minha escolha


5
Para mim, isso significaria uma "sempre use break", caso algum programador tenha adicionado um novo caseno final do seu switchsem verificar se breakele existe (isso seria culpa do programador, mas é melhor estar seguro - por qualquer motivo, porque você pode ser que programador em 6 meses-)
SJuan76

@ SJuan76 Sim, eu concordo, é melhor prevenir do que remediar, se você deseja manter uma proteção para erros futuros, você deve incluir um no final.
Suvarna Pattayil

1
Com esse argumento em mente, você também pode argumentar que sempre terá , no final de matrizes, caso um novo valor seja inserido. No entanto que quebra alguns códigos e geralmente parece :) feio
Robin Castlin

1
@Robin Colocar uma vírgula é diferente. Se não estiver lá e alguém adicionar um novo valor a uma matriz, eles receberão um erro de compilação. No entanto, não haverá erro de compilação se a instrução de caso anterior estiver faltando uma interrupção - portanto, seria possível que isso fosse esquecido e causasse erros em tempo de execução.
Keith Miller

@RobinCastlin Desde que o idioma permita que você coloque um ,. No caso, defaultfoi projetado para ser o último caso. Talvez o idioma considere um breakdepois dele como um erro. Supondo que breakfosse permitido apenas um diferenciador entre dois casos.
Suvarna Pattayil
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.