Unintended variable shadowing
In golang, you need to be careful while declaring your variables for re-using.
If you declare a variable in a block and re-declare in an inner block, you will face the variable shadowing situation! Let’s see what I mean;
package main
import (
"fmt"
"time"
)
func getFunnyName() string {
return "jambalaya"
}
func main() {
var name string // declare name
name = "none"
if time.Now().Year() > 1984 {
// this is totally different variable
// in an inner block and shadows
// var name string
name := getFunnyName()
// name jambalaya
fmt.Println("name", name)
} else {
fmt.Println("name", name)
}
// name final value none
fmt.Println("name final value", name)
}
as you see, name := getFunnyName()
is in the inner block and totally different
declaration. It has nothing to do with var name string
.
How do we fix that? First we need to check shadow issues via go vet
. You need
to install;
go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow@latest
then you need to run it over your code;
go vet -vettool=$(command -v shadow) main.go
# command-line-arguments
./main.go:20:3: declaration of "name" shadows declaration at line 13
Yep! here it is, you catch the bug! now, it’s time to fix the code;
package main
import (
"fmt"
"time"
)
func getFunnyName() string {
return "jambalaya"
}
func main() {
var name string // declare name
name = "none"
if time.Now().Year() > 1984 {
// this set real name value
name = getFunnyName()
// name jambalaya
fmt.Println("name", name)
} else {
fmt.Println("name", name)
}
// name final value jambalaya
fmt.Println("name final value", name)
}
always keep this in mind, whenever you write if
blocks or ;
in your checks
such as;
if variable := expression; variable != nil {
// do your thing...
}
this means everything happens in your defined block scope!