Golang provides a simple way of executing code after a func has ended using the defer statement. A simple example to start off.
func rundefer() {
defer fmt.Printf("and this is printed after execution")
fmt.Printf("this is printed first")
}
Result:
this is printed first
and this is printed after execution
Now I thought we could measure how long a func takes simply by using defer like this
func rundefer() {
t := time.Now()
// calculate the duration of the func
// when we exit out of this func
defer fmt.Printf("rundefer running time:%s\n",time.Since(t))
time.Sleep(time.Millisecond * 500)
}
result:
rundefer running time:0s
However, it turns out that the above deferred call’s arguments are evaluated immediately which results in a result being printed of: 0 seconds! Not what we wanted, and we need a different way of defining the defer execution….
The following example ensures the argument that prints the running time is defined as a func itself. Now this func is still evaluated immediately (as a func) but this func is not executed until the defer is really hit.
The solution example therefore:
func rundeferasfunc() {
t := time.Now()
defer func() {
fmt.Printf("rundeferasfunc running time:%s\n",time.Since(t))
}()
time.Sleep(time.Millisecond * 500)
}
result:
rundeferasfunc running time:500ms
Running the code in defers in a defined func therefore ensures the execution is really only evaluated after the func that calls the defer has ended! The full golang example can be found at the go playground: