Skip to main content


Showing posts from January, 2015

Failing to RTFM for Go: defer statements

So, a colleague wanders over the says: "You know that commit you just made to project X? It doesn't work" and the proceeds to remind me of that fact that the defer statement in Go is rather special. The argument of the defer statement is a function that will be called when the defer statement executes. But its arguments are evaluated when the defer statement is encountered (here's where you, or at least I, RTFM ). A function like this won't do what you expect: func deferPrintf() error { var err error defer fmt.Printf("deferPrintf: err has value %v\n", err) err = errors.New("Error 2") return err } That will always output deferPrintf: err has value because the function being called ( fmt.Printf ) by the defer has its arguments (which include err ) evaluated when the defer is encountered. Oops. I'd forgotten that. The solution is pretty simple. Wrap the fmt.Printf in a closure like this: func useAClosure() err