Interrompere il caso predefinito nello switch


88

Sono un po 'perplesso ogni volta o meno da includere breakdopo l'ultimo caso, spesso default.

switch (type) {
    case 'product':

        // Do behavior

        break;
    default:

        // Do default behavior

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

breakIl mio unico scopo è nella mia comprensione impedire che il codice switchvenga eseguito per il resto del caso.

È quindi più logico avere un breakultimo a causa di coerenza o saltare per breaknon applicare alcun uso funzionale? Entrambi sono logici in modi diversi secondo me.

Questo potrebbe in un certo senso essere confrontato con la fine di un .phpfile con ?>. Non finisco mai per ?>lo più a causa del rischio di produrre spazi vuoti, ma si potrebbe sostenere che sarebbe logico terminare il file.

Risposte:


144

breaknon è tecnicamente necessario dopo l'ultima alternativa (che, intendiamoci, non deve essere default: è perfettamente legale, e talvolta anche utile mettere al defaultprimo posto il ramo); se il tuo codice cade alla fine switchdell'istruzione o breaksalla fine del suo ultimo ramo ha lo stesso risultato.

Tuttavia, terminerei comunque ogni ramo, incluso l'ultimo, con un'istruzione returno break, per tre motivi:

  1. Refactorability. Se tutti i rami terminano con breako return, puoi riordinarli senza modificarne il significato. Ciò rende meno probabile per un tale riordino introdurre una regressione.
  2. Coerenza e minima sorpresa. La coerenza dice che i tuoi rami dovrebbero finire in modo coerente, a meno che non siano effettivamente diversi nel significato. Il principio di Least Surprise impone che cose simili dovrebbero apparire simili. Terminare l'ultimo ramo di un switchblocco esattamente come i precedenti soddisfa entrambi, il che rende più facile la lettura e la comprensione. Se si esclude l'esplicito break, l'ultimo ramo sarà otticamente diverso (il che è particolarmente importante per la scansione rapida) e per vedere che non è davvero diverso, il lettore deve scendere al livello di nitidezza della lettura delle singole dichiarazioni .
  3. Proteggiti. Se prendi l'abitudine di terminare tutti i tuoi switchrami con un break, diventerà automatico dopo un po 'e avrai meno probabilità di dimenticarlo accidentalmente dove è importante. Addestrare te stesso ad aspettarti la breakfine di ogni ramo aiuta anche a rilevare le breakdichiarazioni mancanti , il che è ottimo per il debug e la risoluzione dei problemi.

Grazie per la tua comprensione in questo! Will breakultimo caso lontato :)
Robin Castlin

7
In C #, break(o altra istruzione del flusso di controllo che esce dal case) è tecnicamente necessario dopo l'ultima alternativa.
dan04,

3
@ dan04: sì, buon punto. C # è un'eccezione qui, ed è probabilmente perché i progettisti del linguaggio erano a conoscenza dei problemi con il switchfall-through nelle lingue esistenti e volevano prevenirli. Le regole che C # impone praticamente corrispondono alle raccomandazioni della mia risposta.
tdammers,

Di che lingua stai parlando in particolare? C? C ++? C #? Giava? PHP?
svick,

2
Un buon compilatore tratterebbe il finale breakcome un NO-OP invece di generare un jmpper l'istruzione successiva, giusto?
Nathan Osman,

11

Data l'ambiguità che esiste nell'uso della switch-casemaggior parte delle lingue, quando lo uso suggerirei sempre di usare breakun'istruzione, tranne quando è esplicitamente e per progettazione non desiderata .

In parte ciò è dovuto al fatto che ogni casechiamata ha lo stesso aspetto, il che a mio avviso migliorerebbe la leggibilità. Significa anche se qualcuno (anche tu) sceglie di inserire un casedopo l'ultimo in una fase successiva, non è necessario preoccuparsi di controllare il blocco precedente, il che potrebbe aiutare a ridurre i bug quando si aggiunge un nuovo codice.


7
Quando voglio che un caso passi al successivo (e non è il caso degenerato di case foo: case bar: ...) inserisco un commento esplicito in cui voglio che avvenga il fall-through. Lo rende molto più chiaro.
Donal Fellows,

3
Sì, come un semplice commento // no breakal posto dibreak;
Pacerier,

O un [[fallthrough]]attributo in caso di C ++.
Ruslan,

1

Non è breaknecessario dopo l' ultimo caso. Uso la parola " ultimo " (non predefinito ) perché non è necessario il caso predefinito è l'ultimo caso.

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

default:
//do default work
break;

case 3:
//do stuff

}

E sappiamo che a break è necessario tra due cases consecutivi . A volte, uso if(a!=0)nel mio codice per una maggiore leggibilità quando altri fanno riferimento al mio codice. Posso scegliere di usare if(a), sarebbe una mia scelta


5
Per me ciò significherebbe una "usa sempre l'interruzione", nel caso in cui un programmatore ne aggiungesse uno nuovo casealla fine del tuo, switchsenza controllare che breakesistesse (sarebbe colpa di quel programmatore, ma sarebbe meglio essere al sicuro, se per qualsiasi motivo, perché potresti essere quel programmatore tra 6 mesi-)
SJuan76,

@ SJuan76 Sì, sono d'accordo, meglio prevenire che curare, se vuoi salvaguardare errori futuri, devi includerne uno alla fine.
Suvarna Pattayil,

1
Con questo argomento in mente, potresti anche sostenere di avere sempre , alla fine degli array nel caso in cui venga inserito un nuovo valore. Tuttavia, che rompe alcuni codici e in generale sembra brutto :)
Robin Castlin

1
@Robin Inserire una virgola è diverso. Se non è presente e qualcuno aggiunge un nuovo valore a un array, verrà visualizzato un errore di compilazione. Tuttavia, non si verificherà alcun errore di compilazione se l'istruzione case precedente non presenta un'interruzione, quindi sarebbe possibile che questo non venisse perso e causasse errori di runtime.
Keith Miller,

@RobinCastlin A condizione che la lingua ti abbia permesso di inserire un ,. In ogni caso, è defaultstato progettato per essere l'ultimo caso. Forse la lingua considererebbe un breakdopo come un errore. Supponendo che breakè stato permesso come elemento di differenziazione solo tra due casi.
Suvarna Pattayil,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.