Storia della questione:
Defer è stato introdotto in Swift (ispirato a somiglianze in Go, C#) per garantire la pulizia delle risorse anche in caso di errori, uscita dalla funzione o ritorno di valori da diversi punti delle funzioni.
Problema:
Liberazione prematura, pulizie delle risorse dimenticate (ad esempio, chiusura di file, logging, rollback di transazioni). A volte si confonde l'ordine di esecuzione, erroneamente ritenendo che defer venga eseguito nel momento della dichiarazione.
Soluzione:
Defer è un blocco speciale che ritarda l'esecuzione del codice fino alla fine dell'ambito corrente (scope), di solito una funzione. Tutti i defer vengono eseguiti in ordine inverso rispetto al loro posizionamento (LIFO). Questo consente di gestire centralmente la pulizia delle risorse, il rilascio di memoria o il rollback di transazioni.
Esempio di codice:
func processFile() { let file = File("/tmp/data.txt") file.open() defer { file.close() print("File chiuso") } // Lavorare con il file print("Lettura dati…") }
Caratteristiche chiave:
Il codice all'interno di defer viene eseguito in caso di crash dell'applicazione (crash) prima dell'uscita dalla funzione?
No, il codice defer viene eseguito solo in caso di uscita corretta dall'ambito (scope). Se l'app si arresta anormalmente (ad esempio, errore fatale), defer non verrà eseguito.
È possibile utilizzare return all'interno di defer?
No, non è possibile. Il blocco defer non consente il ritorno di valori o la fine dell'ambito, solo istruzioni.
Può defer essere utilizzato per modificare le variabili dichiarate prima di defer?
Sì, defer cattura i valori dallo stack corrente al momento dell'esecuzione. È possibile modificare i valori dichiarati prima di defer e saranno mantenuti all'uscita dallo scope.
Esempio di codice:
func example() -> Int { var result = 0 defer { result = 42 } return result // defer verrà eseguito, risultato — 42 }
Il file viene aperto, ma chiuso solo esplicitamente in fondo alla funzione, e in caso di errori o uscita anticipata dalla funzione il file rimane aperto.
Pro:
Contro:
Utilizzo di defer per chiudere il file subito dopo l'apertura. Anche se si verifica un'eccezione o un ritorno dalla funzione, il file verrà chiuso senza eccezioni.
Pro:
Contro: