As per my New Year's resolution, I've been learning to program in Go and reading The Go Programming Language. On page 141 of the book, there are a couple of code examples to explain scoping rules and how variables are bound to anonymous functions. This short post is just me making sure I grok what's in the book and sharing in case its helpful to anyone else.
Consider this snippet:
mynums is an array of functions. The initialization clause of the for loop creates an implicit lexical block that encloses the variable i. This variable i is in scope through every iteration of the loop. That means that the same i is updated in each iteration and bound to the anonymous function that is appended to mynums by append(mynums, func () { fmt.Println(i) }). When the first entry is appended to mynums, the value of i is 1, but the value is NOT what is bound to the function. The variable itself (the location) is bound. So every iteration appends a function referencing the same variable. At the end, we have ten functions in the array and all of them are bound to the same variable which has one value: 11. If we compile and run the program, it prints out "11", ten times.
This is analogous to the second example on page 141 of the book. Now, consider this code sample:
Here, we add the line j := i and use j for the anonymous function func () { fmt.Println(j)}). j is declared inside the body of the for loop. The scope of j is a particular instance of the for loop. Over ten iteration of the loop, we will declare ten separate instances of j. That means that the first j bound to the anonymous function appended to mynums will have the value 1 and that value will not change. The second iteration will bind a different j that has the value 2. When we execute the various f() at the end, we will get the output we expect, the numbers 1 to 10.
If you're reading the book, which I highly recommend, you may also want to check out the discussion of scope on pages 46-47.
No comments:
Post a Comment