Go has function types and anonymous functions (literals). A closure captures variables from its surrounding lexical scope.
type Op func(int, int) int
var add Op = func(a, b int) int { return a + b }
fn := func(x int) int { return x * 2 }
_ = fn(3)
v := func(x int) int { return x + 1 }(41)
Before Go 1.22, loop variables were reused; closures created in a loop often needed a local copy:
for _, id := range ids {
id := id // copy for closure body
go func() { use(id) }()
}
Since Go 1.22, each iteration has its own id in for loops — but understanding the capture model still matters for readability and older toolchains.
func mapInts(xs []int, f func(int) int) []int {
out := make([]int, len(xs))
for i, v := range xs {
out[i] = f(v)
}
return out
}
Methods bind a receiver; function values are useful for callbacks, middleware, and dependency injection without frameworks.