Go gotcha: Two variables with the same name?

Why isn't the variable n updated in this example?

func main() {
        n := 0
        if true {
                n := 1
                n++
        }
        fmt.Println(n)
}
// Output: 0
Answer

n := 1 declares a new variable which shadows the original n throughout the scope of the if statement.

To reuse n from the outer block, write n = 1 instead.

func main() {
        n := 0
        if true {
                n = 1 // Change from := to =
                n++
        }
        fmt.Println(n) // Prints 2
}

Detecting shadowed variables

To help detect shadowed variables, you may use the experimental -shadow feature provided by the vet tool. It flags variables that may have been unintentionally shadowed. Passing the original version of the code to vet gives the following message:

$ go vet -shadow main.go
main.go:4: declaration of "n" shadows declaration at main.go:2

Additionally, the Go compiler detects and disallows some cases of shadowing:

func Foo() (n int, err error) {
        if true {
                err := fmt.Errorf("Invalid")
                return
        }
        return
}
../main.go:4:3: err is shadowed during return

Comments

Be the first to comment!