Module lessons (2/5)
Multiple returns and named returns
In Go, a function can return multiple values. It's the mechanism that
enables the (value, error) pattern you've already seen and that pervades
the entire standard library.
Multiple returns
The return types go between parentheses, comma-separated:
func divmod(a, b int) (int, int) {
return a / b, a % b
}
q, r := divmod(17, 5) // q=3, r=2They are destructured with multiple assignment. To discard one of the
values use _:
_, r := divmod(17, 5) // solo il restoThe canonical (T, error) pattern
Almost all of the stdlib follows it. error is ALWAYS last:
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
}Named returns
You can name the return values: they become pre-declared variables
initialized to zero, and return with no arguments returns them ("naked
return"):
func divmod(a, b int) (q, r int) {
q = a / b
r = a % b
return // naked: ritorna q, r
}Named returns also appear in documentation tooltips, so they're useful as a form of inline documentation for complex functions — not just for the naked return.
More than two returns?
Nothing stops you from (int, int, int, error), but if you feel the need
it's almost always a sign that you should return a struct:
type Result struct {
Sum int
Avg float64
Max int
}
func analyze(nums []int) (Result, error) { ... }Try it
Define divmod(a, b int) (int, int) that returns quotient and remainder.
Show hint
Return types between parentheses: `(int, int)`.
Solution available after 3 attempts
Implement safeDiv(a, b int) (int, error): if b == 0 return (0, errors.New('divisione per zero')), otherwise (a/b, nil).
Show hint
Error ALWAYS as the last value. On error: zero value + error.
Solution available after 3 attempts
What does this program print, using named returns?
func f() (a, b int) {
a = 1
b = 2
return
}
x, y := f()
fmt.Println(x, y)Recap
- Multiple values between parentheses:
func f() (T1, T2, error). - Convention:
errorALWAYS as the last value; on error, zero value + error. - Named returns pre-declare the variables and enable naked returns.
- Naked returns only in very short functions; beyond that, readability suffers.
- More than 2-3 returns? You probably want a struct.