Go by Example: Defer Statements
Go 1.23
Understand the `defer` keyword, used to schedule function calls to run after the surrounding function completes. This example demonstrates its LIFO execution order and its critical role in resource cleanup, such as closing files or unlocking mutexes.
Code
package main
import (
"fmt"
"os"
)
func main() {
f := createFile("defer.txt")
// Defer closing the file immediately after opening
defer closeFile(f)
writeFile(f)
}
func createFile(p string) *os.File {
fmt.Println("creating")
f, err := os.Create(p)
if err != nil {
panic(err)
}
return f
}
func writeFile(f *os.File) {
fmt.Println("writing")
fmt.Fprintln(f, "data")
}
func closeFile(f *os.File) {
fmt.Println("closing")
err := f.Close()
if err != nil {
fmt.Fprintf(os.Stderr, "error: %v
", err)
os.Exit(1)
}
}Explanation
Defer is used to ensure that a function call is performed later in a program's execution, usually for purposes of cleanup. defer is often used where e.g. ensure and finally would be used in other languages.
When you defer a function call, it is pushed onto a stack. When the surrounding function returns, the deferred calls are executed in last-in-first-out order. This makes it easy to keep cleanup code close to the resource creation code.
Common uses for defer:
- Closing file handles
- Releasing mutex locks
- Closing database connections
- Printing footer logs
Code Breakdown
11
The closeFile function is scheduled to run when main() exits. By placing it right after createFile, we ensure the file is closed regardless of how the function exits (return or panic).
13
We perform operations on the file. Even if writeFile panicked, the deferred closeFile would still execute.

