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: