-1

I am calling the following function

func main() {
    defer func(t time.Time) {
        log.Printf("took=%v", time.Since(t))
    }(time.Now())
    time.Sleep(5 * time.Second)
}

I noticed that as expected, the deferred function reports the actual entire time of execution.

▶ go run main.go
2022/01/08 15:20:03 took=5.005078652s

My question is what is the actual mechanism that allows this?

Does this line defer func(t time.Time) imply that at this specific point the invocation is actually done (therefore t takes the temporal value at this point in time) and that is the way it can estimate the actual (main) function invocation?

Otherwise, it the deferred anonymous function was entirely invoked just before main's exist, how would it know when main actually begun execution?

pkaramol
  • 16,451
  • 43
  • 149
  • 324
  • 2
    The function is not invoked, but its parameters are evaluated, which means `time.Now()` is called. – icza Jan 08 '22 at 13:22
  • 1
    From https://go.dev/ref/spec#Defer_statements: "Each time a "defer" statement executes, the function value and parameters to the call are evaluated as usual and saved anew but the actual function is not invoked. Instead, deferred functions are invoked immediately before the surrounding function returns, in the reverse order they were deferred." So no, "the invocation is actually done" is wrong. – Volker Jan 08 '22 at 13:22

1 Answers1

3

Yes, this is what even Go tour says:

The deferred call's arguments are evaluated immediately, but the function call is not executed until the surrounding function returns.

Arkadiusz Drabczyk
  • 11,227
  • 2
  • 25
  • 38