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:
func divmod(a, b int) (int, int) {
return a / b, a % b
}
q, r := divmod(17, 5) // q=3, r=2Si destrutturano con assegnazione plurale. Per scartare uno dei valori usa
_:
_, r := divmod(17, 5) // solo il restoIl pattern canonico (T, error)
Quasi tutta la stdlib lo segue. error è SEMPRE l'ultimo:
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"):
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:
type Result struct {
Sum int
Avg float64
Max int
}
func analyze(nums []int) (Result, error) { ... }Prova tu
Definisci divmod(a, b int) (int, int) che ritorna quoziente e resto.
Mostra suggerimento
Tipi di ritorno tra parentesi: `(int, int)`.
Soluzione disponibile dopo 3 tentativi
Implementa safeDiv(a, b int) (int, error): se b == 0 ritorna (0, errors.New('divisione per zero')), altrimenti (a/b, nil).
Mostra suggerimento
Errore SEMPRE come ultimo valore. In caso di errore: valore zero + errore.
Soluzione disponibile dopo 3 tentativi
Cosa stampa questo programma con ritorni nominati?
func f() (a, b int) {
a = 1
b = 2
return
}
x, y := f()
fmt.Println(x, y)Recap
- Più valori tra parentesi:
func f() (T1, T2, error). - Convenzione:
errorSEMPRE 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.