Why I can redefine the same variable multiple times in a for loop but can't outside of a loop?

There are a couple of things here. First let's address the second half of your question.

The default way to declare a variable is using the var keyword and then assign to it with the = operator.

var a int
a = 77

Go allows us a shortcut := that both declares a variable and assigns a value

a := 77

In your example when you use := a second time you're trying to redeclare a new variable named a in the same scope which is not allowed. The error no new variables on left side of := is trying to tell you this.

But now to your original question, why can you do this multiple times inside a for loop?

The reason is each time you enter a block of curly braces {} you're creating a new nested scope. When you declare the variable x at the top of the loop it is a new variable and it goes out of scope at the end of the loop. When the program comes back around to the top of the loop again it's another new scope.

For example look at this code

{
    x := 77
    fmt.Println(x)
}
fmt.Println(x) // Compile error

That second Println fails because x does not exist in that scope.


No identifier may be declared twice in the same block, and no identifier may be declared in both the file and package block.

And see: What is the difference between := and = in Go?


You have new variable on each run of for here,
This code shows it by printing the address of x (The Go Playground):

package main

import (
    "fmt"
)

func main() {
    for i := 0; i < 2; i++ {
        x := 77
        fmt.Println(&x)
    }
}

output:

0x1040e0f8
0x1040e0fc

And if you need new variable in your second example you may shadow it (The Go Playground):

package main

import (
    "fmt"
)

func main() {
    a := 77
    fmt.Println(&a)
    {
        a := 77
        fmt.Println(&a)
    }
}

output:

0x1040e0f8
0x1040e0fc

Also See: Where can we use Variable Scoping and Shadowing in Go?

Tags:

Variables

Go