Introduction
A closure is a function value that references variables from outside its own body. Because functions in Go are first-class values, a function literal can be defined inline and returned from another function, carrying a reference to the variables it captured from its enclosing scope. This allows the closure to read and modify that state across multiple calls.
Cricket analogy: A commentator who has watched every over remembers the exact match situation and references it in every sentence, just as a closure carries a live reference to the variables from its enclosing scope, not just a copy from one moment.
Syntax
func makeCounter() func() int {
count := 0
return func() int {
count++
return count
}
}Explanation
In makeCounter, the variable count is declared inside the outer function. The anonymous function returned by makeCounter captures count by reference, not by copying its value. Each time the returned function is called, it increments and returns the same count variable, so the state persists between calls. Every call to makeCounter() creates a brand-new, independent count variable, so separate closures do not share state unless they explicitly close over the same variable.
Cricket analogy: The count variable inside makeCounter is like a personal wicket tally kept by a specific bowler; each delivery updates that same tally, but a different bowler brought in via a fresh spell (a new makeCounter() call) starts their own tally at zero, unrelated to the first.
Example
package main
import "fmt"
func makeCounter() func() int {
count := 0
return func() int {
count++
return count
}
}
func main() {
counterA := makeCounter()
counterB := makeCounter()
fmt.Println(counterA())
fmt.Println(counterA())
fmt.Println(counterA())
fmt.Println(counterB())
}
// Output:
// 1
// 2
// 3
// 1Key Takeaways
- A closure is a function value that captures variables from its enclosing scope.
- Captured variables are referenced, not copied, so state persists across calls.
- Each invocation of the outer function creates a fresh, independent set of captured variables.
- Closures are commonly used to build counters, generators, and stateful callbacks.
- Since functions are first-class values, closures can be returned, stored, and passed around freely.
Practice what you learned
1. What is a closure in Go?
2. How does a closure capture an outer variable in Go?
3. In the makeCounter example, why do counterA and counterB return independent sequences?
4. Which Go feature makes closures possible?
Was this page helpful?
You May Also Like
Functions in Go
Learn how to declare, call, and use functions as first-class values in Go.
Variadic Functions in Go
Learn how to write and call functions that accept a variable number of arguments.
Methods in Go
Learn how to attach methods to types in Go using value and pointer receivers.
Goroutines in Go
Goroutines are lightweight, runtime-managed threads that let Go programs run functions concurrently with minimal overhead.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics