1

I am trying to understand some go code. I have provided a runnable example and output. The output is printing the value 10 for every defer function that gets called. I would have expected incrementing values to be returned. If I don't call the print from a function it works as expected.

Is go passing i by reference (not by value) and since defer runs at the end of a function life cycle i is effectively 10 in memory so it prints 10? I couldn't find anything to explain what is exactly happening here.

package main

import "fmt"

func main() {
    fmt.Println("counting")

    for i := 0; i < 10; i++ {
        defer func() {fmt.Println(i)}()
    }

    fmt.Println("done")
}

Output

counting
done
10
10
10
10
10
10
10
10
10
10
Ryan-Neal Mes
  • 6,003
  • 7
  • 52
  • 77
  • 2
    Essentially the same as https://golang.org/doc/faq#closures_and_goroutines – JimB May 15 '20 at 20:44
  • 2
    You'll also see that `go vet` will flag this, so any test of this code would fail. – JimB May 15 '20 at 20:54
  • Note that `i` is not *passed* at all: it's *inherited* via closure. Inheritance like this is equivalent to Algol's pass-by-name, though, so if you want to equate it to argument passing, it's neither by-reference nor by-value, but by-name. – torek May 15 '20 at 21:07

0 Answers0