In Golang, we often declare variables with :=, which is convenient but can cause some problems. Shadowing is easy to create when variables encounter scope.

For example, we often encounter:

shadow: declaration of “err” shadows declaration

What is variable hiding?

When a variable of the same name is redeclared, the value of the preceding variable will be obscured by the value of the preceding variable, although the two variables have different values. This can easily lead to problems.

Here’s an example:

Func main() {n := 0 if true {n := 1 n++} FMT.Println(n) // 0Copy the code

Here n++ doesn’t apply to n outside because it’s redeclared in the if scope.

What if I assign n directly to the inside instead of redeclaring it?

Func main() {n := 0 if true {n= 1 n++} FMT.Println(n) // 2Copy the code

Such an obvious situation is easy to find when we write code, but if it is very complex code, especially when encountering err, it is really easy to Shadowing.

Here’s another chestnut:

func templateToFile(templateFilename string, filename string, data interface{}) (err error) {





        if f, err := os.OpenFile(filename, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666); err == nil {

                defer f.Close()





                if t, err := template.ParseFiles(templateFilename); err == nil {

                        return t.Execute(f, data)

                }

        }

        return

}
Copy the code

Here, the err in the first if scope is not the same thing as the err in the second scope, but it is also a variable with the same name.

This can be done by renaming the second err variable or redeclaring it with an assignment proxy.

So how do you detect this variable masking?

In severe cases your code will fail directly, but in less severe cases your code will run, but there will still be shadowing.

1, Vet can be used,Go 1.12 and above version is required

go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow

go vet -vettool=$(which shadow)
Copy the code

2. You can also use Goland’s Tool (I usually use this)

3, you can also use the golangci-Lint tool, which can also be detected.