幽灵变量(Shadowed Variables)
Example 1
如果你在新的代码块中像下边这样误用了 :=,编译不会报错,但是变量不会按你的预期工作:
func main() {
x := 1
println(x) // 1
{
println(x) // 1
x := 2
println(x) // 2 // 新的 x 变量的作用域只在代码块内部
}
println(x) // 1
}
这是 Go 开发者常犯的错,而且不易被发现。
Example 2
func main() {
n := 0
if true {
n := 1
n++
}
fmt.Println(n) // 0
}
The statement 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
n++
}
fmt.Println(n) // 2
}
Example 3
func BadRead(f *os.File, buf []byte) error {
var err error
for {
n, err := f.Read(buf) // shadows the function variable 'err'
if err != nil {
break // causes return of wrong value
}
foo(buf)
}
return err
}
Rescue
go vet
This analyzer check for shadowed variables. A shadowed variable is a variable declared in an inner scope with the same name and type as a variable in an outer scope, and where the outer variable is mentioned after the inner one is declared.
go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow
go vet -vettool=$(which shadow)
go-nyet
Installation
$ go get github.com/barakmich/go-nyet
这个包的运行方式有三种:目录/包/文件。对应的命令如下:
$ go-nyet ./...
# or
$ go-nyet subpackage
# or
$ go-nyet file.go
实际使用
使用方法如下:
> $GOPATH/bin/go-nyet main.go
main.go:10:3:Shadowing variable `x`
Reference
- https://www.cnblogs.com/Detector/p/9726930.html
- https://rpeshkov.net/blog/golang-variable-shadowing/