Il pattern matching in Swift consente di estrarre elegantemente i valori e confrontarli con i modelli nelle condizioni switch, nei cicli e negli operatori if case. La caratteristica principale è la possibilità di non solo confrontare i valori, ma anche di estrarre dati associati da strutture complesse, ad esempio enumerazioni con valori associati, opzionali o tuple.
L'operatore case let è spesso utilizzato per estrarre valori annidati, ad esempio:
enum Result { case success(value: Int) case failure(error: Error) } let result: Result = .success(value: 42) switch result { case .success(let value): print("Successo con valore \(value)") case .failure(let error): print("Fallito con errore: \(error)") }
È anche utile applicare il pattern matching quando si lavora con le collezioni:
let items: [Result] = [.success(value: 1), .failure(error: MyError()), .success(value: 42)] for case let .success(value) in items { print("Trovato valore: \(value)") }
È importante ricordare che non tutti i comportamenti dei modelli funzioneranno se la struttura o l'enum sono definite senza valori associati o senza il necessario supporto Equatable. Inoltre, gli sviluppatori inesperti possono sbagliare con exhaustiveness (completezza della considerazione di tutte le varianti dell'enum).
Qual è la differenza tra if let, guard let e if case let quando si lavora con valori opzionali? In quali casi ciascuno di essi è preferibile?
Risposta:
if let e guard let sono utilizzati per estrarre in modo sicuro i valori dagli opzionali.if case let viene applicato non solo agli opzionali, ma anche agli enum con valori associati, ampliando le possibilità di pattern matching.Esempio:
let number: Int? = 42 if case let value? = number { print("Il valore è \(value)") }
value? - pattern che estrae il valore solo se non è nil.
Storia
Un sviluppatore non ha implementato tutti i case per l'enum nello switch. L'aggiunta di un nuovo case nell'enum ha portato a un errore silenzioso, poiché il ramo default era stato aggiunto "per sicurezza". Di conseguenza, parte della logica ha smesso di funzionare e l'errore si è manifestato solo all'utente.
Storia
Nel progetto era stato utilizzato un array
Result<T, Error>e si tentava di filtrare solo i valori di successo attraverso un ciclo normalefor x in.... Ciò portava a controlli manuali del tipo, causando l'ignoranza di parte dei successi a causa di un errore nella condizione.
Storia
Un membro del team non sapeva dell'
if case letcon opzionali e faceva sempre un doppio controllo: primaif number != nil, poi l'estrazione forzata tramite "force unwrap". Questo portava a crash in produzione.