Defer
Il comando defer
registra una funzione che viene eseguita al termine della goroutine corrente o del main.
Se sono registrate più funzioni in defer, esse vengono eseguite in ordine inverso di registrazione.
Le funzioni in defer sono sempre eseguite, anche in caso di panic.
(420defer.go):
package main
import "fmt"
import "os"
func main() {
// Crea un file
f := createFile("/tmp/defer.txt")
// Deferisce la chiusura al termine della funzione main
defer closeFile(f)
// Scrive il file
writeFile(f)
}
func createFile(p string) *os.File {
fmt.Println("creating")
f, err := os.Create(p)
if err != nil {
panic(err)
}
return f
}
func writeFile(f *os.File) {
fmt.Println("writing")
fmt.Fprintln(f, "data")
}
func closeFile(f *os.File) {
fmt.Println("closing")
f.Close()
}
E' buona norma, quando si ottiene una risorsa (file descriptor, connessione a database o rete, ecc), registrare subito in defer la funzione che rilascia la risorsa. Questo è particolarmente importante nel caso di goroutine. Se una goroutine termina e non rilascia una risorsa, le altre routine attive e il main potrebbero non essere più in grado di accedere a tale risorsa.