È necessario aggiungere il caso predefinito durante l'utilizzo di casi di switch?

39

Durante una recente revisione del codice mi è stato chiesto di inserire default di casi in tutti i file ovunque sia utilizzato switch block, anche se non c'è nulla da fare in default . Ciò significa che devo mettere il caso default e non scrivere nulla in esso.

Questa è la cosa giusta da fare? Quale scopo servirebbe?

    
posta Ankit 04.01.2013 - 06:57
fonte

8 risposte

30

Sembra che ci siano tre casi in cui un'istruzione default non è necessaria:

  1. non rimangono altri casi, perché esiste un insieme limitato di valori che immettono switch case . Ma questo potrebbe cambiare nel tempo (intenzionalmente o accidentalmente), e sarebbe bello avere un default case se qualcosa cambia _ è possibile registrare o avvisare l'utente di un valore errato.

  2. sai come e dove verrà utilizzato switch case e quali valori lo inseriranno. Di nuovo, questo potrebbe cambiare e potrebbe essere necessaria un'ulteriore elaborazione.

  3. altri casi non richiedono alcuna elaborazione speciale. Se questo è il caso, penso che ti venga chiesto di aggiungere un default case , perché è uno stile di codifica accettato e rende il tuo codice più leggibile.

I primi due casi si basano su ipotesi. Quindi (supponendo che lavori in una squadra non molto piccola dato che hai periodiche revisioni del codice), non puoi permetterti di fare queste ipotesi. Non sai chi lavorerà con il tuo codice o effettuerà chiamate a funzioni / invocando metodi nel tuo codice. Allo stesso modo, potresti dover lavorare con il codice di qualcun altro. Avere lo stesso stile di codifica renderà più facile gestire il codice di qualcuno (incluso il tuo).

    
risposta data 04.01.2013 - 07:20
fonte
28

Is this the right thiong to do? What purpose would it serve ?

Non è insolito che gli standard di codifica aziendale richiedano un caso predefinito per tutte le dichiarazioni switch . Una ragione è che rende facile per i lettori trovare la fine del switch . Un'altra ragione probabilmente migliore è che ti fa riflettere per un secondo su cosa dovrebbe fare il tuo codice quando la condizione non corrisponde alle tue aspettative. Indipendentemente dal motivo del requisito, se si tratta di uno standard aziendale, dovresti seguirlo a meno che non ci sia un motivo a tenuta d'aria per non farlo.

Se ritieni che il tuo switch includa casi per ogni possibile condizione, allora una buona cosa da fare è mettere un'istruzione assert nel caso predefinito. In questo modo, quando qualcuno cambia il codice e aggiunge inavvertitamente una condizione che switch non copre, colpirà assert e realizzerà che è necessario indirizzare quella parte del codice.

Se switch copre solo alcune delle possibili condizioni, ma non è necessario fare nulla di speciale per gli altri, è possibile lasciare vuoto il caso predefinito. È una buona idea aggiungere un commento in quel caso per indicare che il caso predefinito è intenzionalmente vuoto perché le condizioni che lo colpiscono non hanno bisogno di lavoro da fare.

    
risposta data 04.01.2013 - 07:31
fonte
12

Se si "attiva" il tipo di enumerazione pura, è pericoloso avere un fallback predefinito. Quando in seguito si aggiungono valori al tipo di enumerazione, il compilatore evidenzierà le opzioni con nuovi valori non coperti. Se hai una clausola predefinita, il compilatore rimarrà in silenzio e potresti non vederlo.

    
risposta data 04.01.2013 - 08:24
fonte
9

Per molti aspetti, questa domanda è la stessa di quella spesso richiesta Ho bisogno di una clausola else alla fine di un if / else if ladder che copre ogni opzione .

La risposta è, sintatticamente parlando, no, non lo fai. Ma c'è comunque ...

Una clausola default può essere presente per (almeno) due motivi:

  1. Come gestore degli errori - sicuro, Non dovrebbe mai arrivare qui! è un reclamo che può essere fatto, ma Cosa succede se? Corruzione dei dati, o anche peggio, nessuna convalida dei dati è rotta per il fallimento del programma se non è correttamente intrappolata. In questo caso, non dovrebbe essere una clausola vuota!
  2. Design / Code Coverage - anche nella forma più semplice di un diagramma di flusso, ci sono due route da un'istruzione if e sempre un otherwise da un caso. Non c'è alcuna ragione per non includerli nel codice sorgente.

La mia filosofia è sempre abbastanza semplice: valuta lo scenario peggiore tra le due opzioni e scegli la soluzione più sicura. Nel caso di una clausola else o default vuota, le opzioni del caso peggiore sono:

  • Includili: tre o quattro righe aggiuntive di codice "ridondante".
  • Non includerli: i dati anomali o una condizione imprevista non vengono intrappolati, causando potenzialmente un errore del programma.

overdramatic? Forse ... ma poi il mio software ha il potenziale di uccidere le persone se va male. Preferisco non correre questo rischio.

Per inciso, le linee guida MISRA-C {vedi profilo per affiliation} consiglia una clausola default per ogni switch

    
risposta data 04.01.2013 - 08:05
fonte
6

Java non ti obbliga ad avere un'istruzione "predefinita" ma è buona pratica a averne una tutto il tempo, anche se il codice potrebbe non essere mai raggiunto (in questo momento). Ecco alcuni motivi:

Avendo una clausola predefinita irraggiungibile mostri al lettore del tuo codice che hai considerato i valori e sai cosa stai facendo. Consenti anche modifiche future, ad esempio: viene aggiunto un nuovo valore enum; lo switch non deve ignorare in silenzio il nuovo valore; puoi lanciare un'eccezione lì o fare qualcos'altro.

Per rilevare un valore imprevisto (nel caso in cui non si stia accendendo un enum) che viene passato - potrebbe essere maggiore o minore di quanto previsto, ad esempio.

Per gestire le azioni 'default' - dove gli switch sono per un comportamento speciale. Ad esempio, una variabile può essere dichiarata al di fuori dello switch ma non inizializzata e ogni caso lo inizializza in qualcosa di diverso. In questo caso, l'impostazione predefinita potrebbe inizializzarla su un valore predefinito, in modo che il codice immediatamente successivo all'interruttore non commetta errori / genera un'eccezione.

Anche se decidi di non inserire nulla nell'impostazione predefinita (nessuna eccezione, registrazione, ecc.), anche un commento per dire che hai considerato il fatto che il default non accadrà mai può aiutarti a leggere il tuo codice; ma questo dipende dalle preferenze personali.

    
risposta data 04.01.2013 - 07:19
fonte
2

Vorrei anche aggiungere che dipende dalla filosofia della lingua che stai usando. Ad esempio, in Erlang, dove è un approccio comune a "lasciarlo andare in crash", non definiresti un caso predefinito ma consenti alla tua dichiarazione case di generare un errore se si verifica una situazione non approvata.

    
risposta data 04.01.2013 - 18:06
fonte
0

Dovresti sempre avere un valore predefinito, a meno che tu non abbia coperto in modo soddisfacente e soddisfacente tutti i casi. Non costa nulla ed è un'assicurazione contro l'incapacità di mantenere la tua dichiarazione di switch in un programma in evoluzione.

Se sei davvero sicuro di non preoccuparti di altri casi, il default: break; // non interessa ma l'impostazione predefinita di default dovrebbe essere qualcosa di simile: lanciare un nuovo errore ("valore inatteso");

Allo stesso modo, non si dovrebbe mai "passare attraverso" un costrutto caso non banale senza aggiungere un commento all'effetto che si intende eliminare. Java ha sbagliato questo in fase di progettazione.

    
risposta data 09.01.2013 - 19:12
fonte
-2

Si consideri

enum Gender
{
       MALE ,
       FEMALE ;
}

e

void run ( Gender g )
{
      switch ( g )
      {
           case MALE :
                 // code related to males
                 break ;
           default :
                 assert Gender . FEMALE . equals ( g ) ;
                 // code related to females
                 break ;
      }
}

Direi che è meglio avere un caso MASCHIO, un caso FEMMINILE e un caso predefinito che genera un'eccezione.

Durante la fase di test, il computer controllerà se g è FEMALE. Durante la produzione, il controllo verrà omesso. (Sì, una microottimizzazione!)

Ancora più importante, manterrai il tuo obiettivo di copertura del 100% del codice. Se hai scritto un caso predefinito che genera un'eccezione, come faresti a testarlo?

    
risposta data 05.01.2013 - 04:12
fonte

Leggi altre domande sui tag