title: Captured Closure (for Loop Variable) in Go
body: <p>Shouldn't Go compiler capture <code>for...range</code> loop variables as a locally assigned closure variable?</p>
  
  <p>Long Version:</p>
  
  <p>This caused me some confusion <a href="https://stackoverflow.com/questions/16264289/captured-closure-loop-variable-in-c-sharp-5-0">in C#</a> too and I was trying to understand it; that why it is fixed in C# 5.0 <code>foreach</code> (reason: the loop variable <strong>can not</strong> change inside the body of loop) and the reasoning for not fixing it in C# <code>for</code> loops (reason: the loop variable <strong>can</strong> change inside the body of loop).</p>
  
  <p>Now (to me) <code>for...range</code> loops in Go seems pretty much like <code>foreach</code> loops in C#, but despite the fact that we can not alter those variables (like <code>k</code> and <code>v</code> in <code>for k, v := range m { ... }</code>); still we have to copy them to some local closures first, for them to behave as expected.</p>
  
  <p>What is the reasoning behind this? (I suspect it's because Go treats any <code>for</code> loop the same way; but I'm not sure).</p>
  
  <p>Here is some code to examine described behavior:</p>
  
  <pre><code>func main() {
      lab1() // captured closure is not what is expected
      fmt.Println(" ")
  
      lab2() // captured closure is not what is expected
      fmt.Println(" ")
  
      lab3() // captured closure behaves ok
      fmt.Println(" ")
  }
  
  func lab3() {
      m := make(map[int32]int32)
      var i int32
      for i = 1; i &lt;= 10; i++ {
          m[i] = i
      }
  
      l := [](func() (int32, int32)){}
      for k, v := range m {
          kLocal, vLocal := k, v // (C) captures just the right values assigned to k and v
          l = append(l, func() (int32, int32) {
              return kLocal, vLocal
          })
      }
  
      for _, x := range l {
          k, v := x()
          fmt.Println(k, v)
      }
  }
  
  func lab2() {
      m := make(map[int32]int32)
      var i int32
      for i = 1; i &lt;= 10; i++ {
          m[i] = i
      }
  
      l := [](func() (int32, int32)){}
      for k, v := range m {
          l = append(l, func() (int32, int32) {
              kLocal, vLocal := k, v // (B) captures just the last values assigned to k and v from the range
              return kLocal, vLocal
          })
      }
  
      for _, x := range l {
          k, v := x()
          fmt.Println(k, v)
      }
  }
  
  func lab1() {
      m := make(map[int32]int32)
      var i int32
      for i = 1; i &lt;= 10; i++ {
          m[i] = i
      }
  
      l := [](func() (int32, int32)){}
      for k, v := range m {
          l = append(l, func() (int32, int32) { return k, v }) // (A) captures just the last values assigned to k and v from the range
      }
  
      for _, x := range l {
          k, v := x()
          fmt.Println(k, v)
      }
  }
  </code></pre>
  
  <p>As it is shown in <code>lab1</code>, at the comment <code>// (A)</code> we get just the last values from the <code>range</code>; the output is like printing <code>9,9</code> ten times instead of showing expected result like <code>1,1</code>, <code>2,2</code>, ... (and of-course maps are not necessarily sorted in Go so we may see <code>3,3</code> ten times as the last pair of values; instead of <code>10,10</code> ten times as the last pair of values). The same goes for code at comment <code>// (B)</code> at <code>lab2</code>, which was expected because we are trying to capture outer variables inside the inner scope (I put this one too just to try that). In <code>lab3</code> at code at comment <code>// (C)</code> everything works fine and you will see ten pairs of numbers there like <code>1,1</code>, <code>2,2</code>, ....</p>
  
  <p>I was trying to use <strong>closure+function</strong> as a replacement for <strong>tuple</strong>s in Go.</p>