Go Tutorial · Functions and Methods · Lesson 18 of 30
Go Closures and defer
Anonymous functions, closures, function values and deferred calls.
Functions are values
Functions can be assigned to variables, passed as arguments and returned. An anonymous function that captures variables is a closure:
package main
import "fmt"
func counter() func() int {
count := 0
return func() int {
count++
return count
}
}
func apply(nums []int, f func(int) int) []int {
out := make([]int, 0, len(nums))
for _, n := range nums {
out = append(out, f(n))
}
return out
}
func main() {
next := counter()
fmt.Println(next(), next(), next())
double := func(n int) int { return n * 2 }
fmt.Println(apply([]int{1, 2, 3}, double))
fmt.Println(apply([]int{1, 2, 3}, func(n int) int { return n * n }))
}
Output
1 2 3 [2 4 6] [1 4 9]
Run this on your computer — see “Get Started” for setup.
defer
defer schedules a call to run when the surrounding function returns — perfect for cleanup like closing files or unlocking mutexes. Deferred calls run in last-in, first-out order:
package main
import "fmt"
func work() {
fmt.Println("open resource")
defer fmt.Println("close resource (deferred 1st, runs last)")
defer fmt.Println("flush buffer (deferred 2nd, runs first)")
fmt.Println("doing work")
}
func main() {
work()
}
Output
open resource doing work flush buffer (deferred 2nd, runs first) close resource (deferred 1st, runs last)
Run this on your computer — see “Get Started” for setup.
Test yourself
In what order do multiple deferred calls run?
First in, first outLast in, first outRandomAlphabetical
Show answer
Answer: Last in, first out