Lecții din modul (5/5)
`defer`: curățare garantată
defer amână executarea unui apel până la funcția de anexare
se întoarce. Funcționează chiar dacă funcția iese prin panică. Mai multe defers
în aceeași funcție, executați în ordinea LIFO (Last-In, First-Out).
Este mecanismul idiomatic pentru curățarea resurselor: închiderea fișierelor, deblocarea mutexurilor, eliberarea conexiunilor, restabilirea stării.
Sintaxă și caz de utilizare canonic
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close() // chiamata SEMPRE all'uscita della funzione
// ... usa f liberamente ...
return nilTipic: f.Close(), mu.Unlock(), db.Close(), tx.Rollback(),
recover().
Argumente evaluate imediat, execuția amânată
Când scrieți defer foo(x), x este evaluat la momentul
defer, nu la momentul execuției:
x := 10
defer fmt.Println(x) // cattura 10
x = 99
// quando la funzione ritorna stampa "10", non "99"Comanda LIFO
Amânările se adună și se execută începând cu cea mai recentă:
defer fmt.Println(1)
defer fmt.Println(2)
defer fmt.Println(3)
// output: 3, 2, 1Acest lucru este în concordanță cu semantica resurselor: ultimul deschis este primul să fie închis.
defer + recover: gestionarea panicii
defer este singura modalitate de a intercepta un panic:
func safe() {
defer func() {
if r := recover(); r != nil {
fmt.Println("recuperato:", r)
}
}()
panic("boom")
}Capcană: defer într-o buclă
Punerea defer f.Close() într-o buclă se acumulează amână până la sfârșitul
funcția, nu a fiecărei iterații. Într-o buclă lungă deschideți multe fișiere
și închideți-le numai când funcția iese: risc de scurgere de descriptor de fișier.
// MALE: defer accumulati
for _, path := range paths {
f, _ := os.Open(path)
defer f.Close() // chiude TUTTI alla fine della funzione esterna
// ...
}
// MEGLIO: estrai in una funzione
for _, path := range paths {
elabora(path) // ogni chiamata ha il proprio scope di defer
}Încearcă
Tipăriți „inizio”, apoi amânați tipărirea „fine” cu defer, apoi tipăriți „mezzo”. Ieșirea trebuie să fie: inizio / mezzo / fine.
Afișează indiciu
Amânarea rulează când main() este pe cale să revină.
Soluție disponibilă după 3 încercări
Scrieți trei amânări consecutive care imprimă 1, 2 și 3 în această ordine în cod. Ieșirea va fi 3 / 2 / 1 (LIFO).
Afișează indiciu
Trei amânări în succesiune; amintiți-vă că se execută în ordine inversă.
Soluție disponibilă după 3 încercări
Ce imprimă asta? (notă: argumentele deferă sunt evaluate imediat)
x := 10
defer fmt.Println(x)
x = 99Recapitulare
defer call()amână execuția până când funcția revine.- Amânări multiple = ordin LIFO.
- Argumente evaluate imediat, execuția amânată.
- Folosit pentru curățarea deterministă: fișiere, mutexuri, conexiuni.
defer+recover()interceptează unpanic(rar, la granițe).- Niciodată
deferîntr-o buclă lungă: se acumulează până când funcția exterioară revine.