3

The documenation states:

As a consequence, redeclaration can only appear in a multi-variable short declaration. Redeclaration does not introduce a new variable; it just assigns a new value to the original.

But how does this work in for loops? See this example. It seems that the variable "nextPos", which has a scope outside the loop, actually gets redeclared inside the loop for the inner scope, and thus looses its value for each iteration. This version works though.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
sebdehne
  • 332
  • 3
  • 7
  • Go has block-scope (unlike, say, Javascript). When you declare a variable, it's declared inside its' surrounding block. As you can have nested blocks, you can declare a variable under the same name in an inner block as in an outer. This is called shadowing. – thwd Aug 04 '16 at 07:13

2 Answers2

3

Let's show how it works, with these code samples:

Let's simplify your first sample, see this working sample code (1):

package main

import "fmt"

func main() {
    a := 100
    {
        fmt.Println(a) // 100
        a, b := 0, 0
        fmt.Println(a, b) // 0 0
    }
    fmt.Println(a) // 100
}

output:

100
0 0
100

so a in a, b := 0, 0 is shadowed, this a is new variable,
this is called Variable scoping and shadowing,
and you may name it e.g. c like this code for now to show how it works (2):

package main

import "fmt"

func main() {
    a := 100
    {
        fmt.Println(a) // 100
        c, b := 0, 0
        fmt.Println(c, b) // 0 0
    }
    fmt.Println(a) // 100
}

the output is that same as (1):

100
0 0
100

and lets simplify your next sample code (3):

package main

import "fmt"

func main() {
    a := 0
    b := byte(0)
    {
        fmt.Println(a, b) // 0 0
        a, b = 1, byte(1)
        fmt.Println(a, b) // 1 1
    }
    fmt.Println(a, b) // 1 1
}

output:

0 0
1 1
1 1

so here a and b are the same inside and outside loop.

also see: Where can we use Variable Scoping and Shadowing in Go?
and see: What is the difference between := and = in Go?

Community
  • 1
  • 1
1

That's how the short assignment statement := works. From the specs:

Unlike regular variable declarations, a short variable declaration may redeclare variables provided they were originally declared earlier in the same block (or the parameter lists if the block is the function body) with the same type, and at least one of the non-blank variables is new. As a consequence, redeclaration can only appear in a multi-variable short declaration. Redeclaration does not introduce a new variable; it just assigns a new value to the original.

Thus, in your first example, you can see that there is one new variable, namely nextB, and this re-declares nextPos as well for each loop iteration.

In the second case, both nextB and nextPos have already been declared and hence no re-declaration occurs. Also note that you are using = as the compiler would not allow := for the same reason, i.e. no new variables declared.

abhink
  • 8,740
  • 1
  • 36
  • 48