go

Golang: Defer Gotchas and Hack

bzon

Bryan Sazon

Posted on July 23, 2019

Golang: Defer Gotchas and Hack

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!

💖 💪 🙅 🚩
bzon
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.

Related

Where GitOps Meets ClickOps
devops Where GitOps Meets ClickOps

November 29, 2024

How to Use KitOps with MLflow
beginners How to Use KitOps with MLflow

November 29, 2024