In Swift, le strutture switch ed enum sono implementate con potenti capacità di pattern matching e una severa sicurezza dei tipi, che le differenzia dalla maggior parte degli equivalenti in altri linguaggi.
In C e C++, così come in Objective-C, le enumerazioni sono semplicemente un insieme di valori interi, e gli operatori switch confrontano i valori per corrispondenza. In Swift, le enumerazioni (enum) sono molto più potenti — supportano valori associati, proprietà calcolate e metodi. L'operatore switch supporta il pattern matching, la protezione contro il branching incompleto e lavora con range, tuple, optional e molto altro.
Nei linguaggi tradizionali, switch spesso porta a errori legati all'assenza di exhaustiveness (considerazione completa di tutti i casi), errori di tipo e l'impossibilità di memorizzare in modo sicuro dati aggiuntivi nei casi di enum. Ciò porta a errori in fase di esecuzione anziché di compilazione.
In Swift, switch richiede la gestione completa di tutti i casi, a meno che l'enumerazione non sia esplicitamente contrassegnata come @unknown default. I valori associati consentono di memorizzare elegantemente informazioni aggiuntive nei casi di enum. Esempio:
enum NetworkResult { case success(Int) case failure(String) } func handle(result: NetworkResult) { switch result { case .success(let code): print("Success con codice: \(code)") case .failure(let error): print("Fallimento con errore: \(error)") } }
Caratteristiche chiave:
È sempre necessario scrivere default in switch per enum?
No, se tutti i casi dell'enumerazione sono coperti esplicitamente, default non è necessario. Inoltre, default non è raccomandato senza necessità: il compilatore potrebbe non avvertirti di nuovi casi di enum quando vengono aggiunti.
Posso usare fallthrough per passare automaticamente tra i casi?
Sì, la parola chiave fallthrough è disponibile, ma deve essere usata con cautela. Non trasferisce valori associati, e tali passaggi sono rari nella pratica reale di Swift.
switch number { case 1: print("uno") fallthrough case 2: print("o due") default: print("altro") }
Può un enum in Swift essere confrontato per rawValue, se ha valori associati?
No. Solo le enumerazioni senza valori associati e con rawValue esplicitamente dichiarato possono essere inizializzate e confrontate tramite rawValue.
Un sviluppatore ha aggiunto un caso default in switch per enum NetworkResult, il che ha portato al fatto che quando è stato aggiunto un nuovo caso, la logica di gestione non è stata aggiornata, e il programma "silenziosamente" non ha funzionato correttamente.
Vantaggi: Nessun avviso del compilatore quando si aggiungono casi.
Svantaggi: Gli errori si manifestano durante l'esecuzione dell'applicazione, la logica non si aggiorna automaticamente.
Un dipendente ha rinunciato al default in switch per enum, permettendo al compilatore di identificare l'assenza di gestione per i nuovi casi dopo la loro aggiunta.
Vantaggi: Gli errori vengono identificati in fase di compilazione, il comportamento dell'applicazione diventa più prevedibile.
Svantaggi: Con un gran numero di casi è necessario più codice, ma si guadagna in affidabilità.