Defering a func in golang

by

in

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:

https://play.golang.org/p/i8jb0KGiCIo