Vai al contenuto
eLearner.app
Modulo 3 · Lezione 2 di 512/50 nel corso~12 min
Lezioni del modulo (2/5)

Ritorni multipli e named returns

In Go una funzione può ritornare più valori. È il meccanismo che abilita il pattern (valore, error) che hai già visto e che pervade tutta la libreria standard.

Ritorni multipli

I tipi di ritorno tra parentesi, separati da virgola:

Go
func divmod(a, b int) (int, int) {
    return a / b, a % b
}

q, r := divmod(17, 5) // q=3, r=2

Si destrutturano con assegnazione plurale. Per scartare uno dei valori usa _:

Go
_, r := divmod(17, 5) // solo il resto

Il pattern canonico (T, error)

Quasi tutta la stdlib lo segue. error è SEMPRE l'ultimo:

Go
func read(path string) ([]byte, error) {
    data, err := os.ReadFile(path)
    if err != nil {
        return nil, fmt.Errorf("read %q: %w", path, err)
    }
    return data, nil
}

Ritorni nominati

Puoi dare nome ai valori di ritorno: diventano variabili pre-dichiarate inizializzate a zero, e return senza argomenti le ritorna ("naked return"):

Go
func divmod(a, b int) (q, r int) {
    q = a / b
    r = a % b
    return       // naked: ritorna q, r
}

I ritorni nominati appaiono anche nei tooltip della documentazione, quindi sono utili come forma di documentazione inline per funzioni complesse — non solo per il naked return.

Più di due ritorni?

Niente ti vieta (int, int, int, error), ma se senti il bisogno è quasi sempre segno che dovresti ritornare una struct:

Go
type Result struct {
    Sum  int
    Avg  float64
    Max  int
}

func analyze(nums []int) (Result, error) { ... }

Prova tu

Esercizio#go.m3.l2.e1
Tentativi: 0Caricamento…

Definisci divmod(a, b int) (int, int) che ritorna quoziente e resto.

Caricamento editor…
Mostra suggerimento

Tipi di ritorno tra parentesi: `(int, int)`.

Soluzione disponibile dopo 3 tentativi

Esercizio#go.m3.l2.e2
Tentativi: 0Caricamento…

Implementa safeDiv(a, b int) (int, error): se b == 0 ritorna (0, errors.New('divisione per zero')), altrimenti (a/b, nil).

Caricamento editor…
Mostra suggerimento

Errore SEMPRE come ultimo valore. In caso di errore: valore zero + errore.

Soluzione disponibile dopo 3 tentativi

Quiz#go.m3.l2.e3
Pronto

Cosa stampa questo programma con ritorni nominati?

Go
func f() (a, b int) {
    a = 1
    b = 2
    return
}
x, y := f()
fmt.Println(x, y)
Opzioni di risposta

Recap

  • Più valori tra parentesi: func f() (T1, T2, error).
  • Convenzione: error SEMPRE come ultimo valore; in caso di errore, valore zero + errore.
  • Ritorni nominati pre-dichiarano le variabili e permettono il naked return.
  • Naked return solo in funzioni cortissime; oltre, perde leggibilità.
  • Più di 2-3 ritorni? Probabilmente vuoi una struct.