Functions
Go functions are first-class: pass them as values, return them, store them in struct fields. Multiple returns + named returns are common. Defer runs on function exit — ideal for cleanup.
Multi-return, named returns, closures, defer
EXAMPLE
package main
import (
"errors"
"fmt"
"os"
)
// Multiple returns — the (T, error) idiom
func divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("divide by zero")
}
return a / b, nil
}
// Named returns — pre-declared, can be set without listing them
func bounds(xs []int) (min, max int, err error) {
if len(xs) == 0 {
err = errors.New("empty")
return
}
min, max = xs[0], xs[0]
for _, x := range xs {
if x < min { min = x }
if x > max { max = x }
}
return
}
// Variadic — last param accepts any number of values
func sum(xs ...int) int {
total := 0
for _, x := range xs { total += x }
return total
}
// Closures — capture surrounding variables
func counter() func() int {
n := 0
return func() int { n++; return n }
}
// Defer — runs at function exit (LIFO)
func writeFile(path string) error {
f, err := os.Create(path)
if err != nil { return err }
defer f.Close() // guaranteed close, even on panic
_, err = f.WriteString("hello")
return err
}
func main() {
q, _ := divide(17, 5)
fmt.Println(q, sum(1, 2, 3, 4))
next := counter()
fmt.Println(next(), next(), next())
}
Why it matters
defer + (T, error) + checking err != nil is the rhythm of every Go program. Internalise it and idiomatic Go writes itself.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
func add(a, b int) int { return a + b }
func divmod(a, b int) (int, int) { return a/b, a%b }
q, r := divmod(17, 5)
Try it Yourself »
Exercise
Return type for a function adding two ints.
func add(a, b int)
{ return a + b }
Three letters.
Discussion
Loading…