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.
Effective Go - The Go Programming Language
I sometimes make a mistake that defer
ed functions are evaluated when the function is called but it’s wrong. Here is an example.
package main import ( "fmt" "time" ) type wrapped func() func main() { wrapper(func () { time.Sleep(time.Second * 3) fmt.Println("Hello") }) } func wrapper(f wrapped) { fmt.Println("wrapper() start: ", time.Now().UTC()) defer instrument(time.Now().UTC()) f() fmt.Println("wrapper() end: ", time.Now().UTC()) } func instrument(start time.Time) { fmt.Println("instrument(): ", start) }
$ go run defer.go wrapper() start: 2016-05-23 07:28:37.474091714 +0000 UTC Hello wrapper() end: 2016-05-23 07:28:40.474272645 +0000 UTC instrument(): 2016-05-23 07:28:37.474139821 +0000 UTC
If defer
functions are evaluated at call time, instrument() time must be 3 seconds later.