How to use Golang defer

Defer is a Golang construct that is usually used for code clean-up operations like ensuring you’ve closed a file or unlocked a lock. When defer is called, the call is performed at the end of that particular function call. Multiple defer calls are added to a list that is executed in Last In, First Out (LIFO) order.

In other languages, this functionality is similar to the ensure or finally keywords.

Implementation

In the following examples, we will explore a practical file handling example and then take a closer look at the LIFO ordering of multiple defer calls.

Example 1: file handling

In this example, we will create a file, defer closing it, and call a write call. Notice how the write call happens before the defer call ​despite the apparent ordering in the code. This is because defer is called at the end of the function (main) call.

package main
import (
"fmt"
"os"
)
// code driver with 3 function calls
func main() {
f := createFile("/tmp/defer.txt")
// we defer the close file call so we do not forget to handle
// function executes after the last line of code of main
defer closeFile(f)
writeFile(f)
}
// function creates a file with error checking
func createFile(p string) *os.File {
fmt.Println("creating")
f, err := os.Create(p)
if err != nil {
panic(err)
}
return f
}
// function writes to a file
func writeFile(f *os.File) {
fmt.Println("writing")
fmt.Fprintln(f, "data")
}
// function closes a file with error checking
func closeFile(f *os.File) {
fmt.Println("closing")
err := f.Close()
if err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
}

Example 2: LIFO order

package main
import (
"fmt"
)
func main() {
// notice the LIFO order of output
// Feel free to remove the defer statement and running
for i := 1; i < 5; i++ {
defer fmt.Println(i)
}
}

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved