Golang: Defer Gotchas and Hack
Bryan Sazon
Posted on July 23, 2019
Sample Program
package main
import "fmt"
func main() {
p := person{"john", 15}
defer printPerson(p)
updateAge(&p, 20)
}
type person struct {
name string
age int
}
func printPerson(p person) {
fmt.Printf("Name: %s, Age: %d", p.name, p.age)
}
func updateAge(p *person, newAge int) {
p.age = newAge
}
Run the program.
$ go run main.go
Name: john, Age: 15
I was expecting 20, but I got 15. This is because "The arguments to the deferred function (which include the receiver if the function is a method) are evaluated when the defer executes, not when the call executes.". See effective go - defer.
This means that the time that defer printPerson(p)
was called, that p
is already set in stone.
Workaround
Now, put printPerson(p)
under an anonymous function.
func main() {
p := person{"john", 15}
// defer printPerson(p)
defer func() {
printPerson(p)
}()
updateAge(&p, 20)
}
Run the program.
$ go run main.go
Name: john, Age: 20
Why? The documentation only says the arguments to the deferred function are evaluated when the defer executes. In the modified code above, that deferred function is the anonymous function, and not the function printPerson
. Hack!
💖 💪 🙅 🚩
Bryan Sazon
Posted on July 23, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.