Does defer runs after function returns?

Issue

I’ve been staring at this code and can’t figure out the why of its behavior.

package main

import (
    "fmt"
)

var i int

func example() int {
    defer func() {
        fmt.Println("defer")
        i = 1
    }()

    fmt.Println("first")
    return i
}

func main() {
    fmt.Println(example())
    fmt.Println(i)
}

At first, the expected output for me is:

first
defer
1
1

But, as you can see in the playground the actual output is:

first
defer
0
1

Is it a deferred anonymous function behavior? Nope

So, why is it printing 0?

Solution

Does defer runs after function returns?

Certainly.

So, why is it printing 0?

Because you’re returning 0.

example() returns an int by value. when return i is evaluated, is current value is returned. After that return is evaluated, the defer function executes, changing the value stored at i to 1. But the 0 value is already the return value.

Go makes it possible to modify the return value of a function, but only if the return value has a name.

For example, this returns 1:

func example() (j int) {
   defer func() { j = 1 }()
   return 0
}

But in your case, you’re not naming your return variable, so you can’t modify it in a defer.

Answered By – Daniel Farrell

Answer Checked By – Robin (GoLangFix Admin)

Leave a Reply

Your email address will not be published.