0Pricing
Go Academy · Lezione

defer, funzioni anonime e closure

Chiamate posticipate e valori funzione

defer, funzioni anonime e closure è una lezione Go Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Go Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Go Academy include 4 lezioni in totale.

defer: esecuzione differita

defer programma una chiamata di funzione da eseguire quando la funzione circostante restituisce il controllo, indipendentemente da come termina (normalmente, con un errore o con un panic):

func readFile(path string) {
    f, err := os.Open(path)
    if err != nil { return }
    defer f.Close() // runs when readFile returns
    // read from f...
}

Ordine di valutazione di defer

Le chiamate differite vengono inserite in uno stack ed eseguite in ordine LIFO (last-in, first-out):

func main() {
    defer fmt.Println("third")
    defer fmt.Println("second")
    defer fmt.Println("first")
    // Output: first, second, third
}

defer per la pulizia

defer è il modo idiomatico per garantire il rilascio delle risorse:

  • Sbloccare un mutex dopo averlo bloccato
  • Chiudere un file dopo averlo aperto
  • Eseguire il commit o il rollback di una transazione del database
  • Chiamare WaitGroup.Done() dopo WaitGroup.Add()

defer con argomenti

Gli argomenti di una chiamata differita vengono valutati immediatamente quando viene chiamato defer, non quando la chiamata viene eseguita:

x := 10
defer fmt.Println(x) // prints 10, not 20
x = 20
fmt.Println(x)       // prints 20

Funzioni anonime

Le funzioni anonime (function literal) vengono definite direttamente, senza un nome:

double := func(n int) int {
    return n * 2
}
fmt.Println(double(5)) // 10

// Immediately invoked:
result := func(a, b int) int { return a + b }(3, 4)

Closure

Una closure è una funzione che cattura variabili dall'ambito circostante:

func makeCounter() func() int {
    count := 0
    return func() int {
        count++
        return count
    }
}

ctr := makeCounter()
fmt.Println(ctr(), ctr(), ctr()) // 1 2 3

Insidia della cattura nelle closure nei cicli

Le closure catturano le variabili per riferimento: un problema comune nei cicli con goroutine:

for i := 0; i < 3; i++ {
    i := i // create a new variable per iteration
    go func() { fmt.Println(i) }()
}

defer con valori di ritorno denominati

Le funzioni differite possono modificare i valori di ritorno denominati, una possibilità utile per aggiungere informazioni agli errori:

func doWork() (err error) {
    defer func() {
        if err != nil {
            err = fmt.Errorf("doWork: %w", err)
        }
    }()
    return riskyOp()
}

Pattern funzionali con le closure

Le closure consentono pattern funzionali come la memoizzazione:

func memoize(f func(int) int) func(int) int {
    cache := map[int]int{}
    return func(n int) int {
        if v, ok := cache[n]; ok {
            return v
        }
        v := f(n)
        cache[n] = v
        return v
    }
}

Closure come middleware

Le closure sono il componente fondamentale del middleware nei server HTTP Go: racchiudono un handler e aggiungono comportamento prima e dopo di esso:

func withLogging(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        log.Printf("%s %s", r.Method, r.URL)
        next(w, r)
    }
}

Verifica rapida

Quando vengono valutati gli argomenti di una chiamata di funzione differita?

Riepilogo: defer, closure e funzioni anonime

Queste funzionalità rendono il codice Go espressivo e sicuro:

  • defer garantisce la pulizia all'uscita dalla funzione, in ordine LIFO
  • Gli argomenti di defer vengono valutati immediatamente
  • Le funzioni anonime possono essere assegnate a variabili o chiamate direttamente
  • Le closure catturano le variabili circostanti per riferimento
  • Faccia attenzione ai problemi di cattura delle variabili dei cicli nelle goroutine

Prossimo corso: array, slice e map.

Domande Frequenti

La lezione «defer, funzioni anonime e closure» è gratuita?

Sì — il testo completo di «defer, funzioni anonime e closure» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Go Academy, passa a CoddyKit PRO. Il corso Go Academy include 4 lezioni in totale.

Cosa imparerò in «defer, funzioni anonime e closure»?

Chiamate posticipate e valori funzione Eserciti Go Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Go Academy?

Non è richiesta alcuna esperienza precedente. Go Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «defer, funzioni anonime e closure»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Go Academy?

Sì. Ogni lezione Go Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Basi e firme delle funzioni
  2. Più valori restituiti
  3. Funzioni variadiche
  4. defer, funzioni anonime e closure
← Torna a Go Academy