Clean-up that can't be forgotten
Open a file, lock a mutex, start a timer — and every path out of the function, including early returns and crashes, must undo it. In many languages that means try/finally blocks or remembering to call close() everywhere. Go has a one-word answer, defer, right next to the line that needs the clean-up.
Functions in Go are also values: you can store them, pass them and return them, and they can capture variables from around them. Today you'll write variadic functions, closures that remember state, and a function that survives a panic.
Results, names and ...
A Go function can return several results — usually a value and an error: func divide(a, b float64) (float64, error). Results can be named, which declares them as variables at the start of the function; a bare return then returns their current values (mistakes #43–#44: helpful for documentation, but don't let a named result shadow something by accident).
package main
import "fmt"
func minMax(nums ...int) (lo, hi int) {
if len(nums) == 0 {
return
}
lo, hi = nums[0], nums[0]
for _, n := range nums[1:] {
lo = min(lo, n)
hi = max(hi, n)
}
return
}
func main() {
fmt.Println(minMax(4, 9, 1))
scores := []int{70, 85}
fmt.Println(minMax(scores...))
fmt.Println(minMax())
}A variadic function takes any number of trailing arguments as a slice. fmt.Println is one: its signature is func Println(a ...any).