user12211419
user12211419

Reputation:

How does the defer keyword in Golang actually work

I had this code:

defer common.LogWarning(
    "b09ee123-f18b-46a8-b80d-f8361771178d:",
    resp.Body.Close(),  // gets called immediately, is *not* deferred..
)

and common.LogWarning is simply like this:

func LogWarning(uuid string, err error) {
    if err != nil {
        log.Warning(uuid, err)
    }
}

the problem is that resp.Body.Close() gets called immediately - that call is not deferred, so how does this work? Why is not the whole code block get deferred?

Upvotes: 0

Views: 197

Answers (3)

thwd
thwd

Reputation: 36

The defer statement defers the function call. The arguments to the function are evaluated immediately.

Use an anonymous function to accomplish your goal:

defer func() {
    common.LogWarning("b09ee123-f18b-46a8-b80d-f8361771178d:",
          resp.Body.Close())
}()

The call represented by the trailing () is deferred.

Upvotes: 2

chash
chash

Reputation: 4423

From the documentation:

The behavior of defer statements is straightforward and predictable. There are three simple rules:

  1. A deferred function's arguments are evaluated when the defer statement is evaluated.

Upvotes: 3

Burak Serdar
Burak Serdar

Reputation: 51512

defer defers the execution of a function until the current function returns. The arguments to the function are evaluated immediately.

https://tour.golang.org/flowcontrol/12

If you need to defer a code block where all evaluations are to be deferred, make it a function:

defer func() {
  // Stuff to defer here
}()
``

Upvotes: 2

Related Questions