Re: [go-nuts] Variable declaration inside loop

1,101 views
Skip to first unread message

David Symonds

unread,
May 19, 2013, 7:24:55 PM5/19/13
to Tobia, golan...@googlegroups.com
On Sun, May 19, 2013 at 11:05 AM, Tobia <tobia.c...@gmail.com> wrote:

> But the following surprised me. I expected it to "fail" (print five 5),
> instead it prints from 0 to 4:
>
> for i := 0; i < 5; i++ {
> x := i
> go func() {
> time.Sleep(time.Millisecond)
> fmt.Println(x)
> }()
> }
> time.Sleep(2 * time.Millisecond)

Your "x := i" line is declaring a new variable for each iteration of
the loop, so each closure captures a new x.

Péter Szilágyi

unread,
May 19, 2013, 7:26:16 PM5/19/13
to Tobia, golang-nuts
Since you're declaring the x inside a block, by the language specs those 5 x-es will be completely different. The optimization is actually noticing that you can reuse it (not in this case).


On Sun, May 19, 2013 at 8:05 PM, Tobia <tobia.c...@gmail.com> wrote:
Hi

I was playing around with closures and I noticed something curious.

First, the obvious behavior. This prints five 5, as expected*:

for i := 0; i < 5; i++ {
go func() {
time.Sleep(time.Millisecond)
fmt.Println(i)
}()
}
time.Sleep(2 * time.Millisecond)


(* There is only one "i" variable in memory, the closure merely captures it. By the time the five goroutines stop sleeping, the single "i" already contains 5.)

This prints the numbers from 0 to 4 (in unpredictable order), again as expected:

for i := 0; i < 5; i++ {
go func(x int) {
time.Sleep(time.Millisecond)
fmt.Println(x)
}(i)
}
time.Sleep(2 * time.Millisecond)


But the following surprised me. I expected it to "fail" (print five 5), instead it prints from 0 to 4:

for i := 0; i < 5; i++ {
x := i
go func() {
time.Sleep(time.Millisecond)
fmt.Println(x)
}()
}
time.Sleep(2 * time.Millisecond)


Why does a single (lexical) variable declaration cause many memory allocations? Would it always do so, or is this a case of the compiler being "smart" and noticing that the variable is being captured? More importantly, is this specified in the reference docs? Can it be relied upon?

-Tobia

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Reply all
Reply to author
Forward
0 new messages