Go语言的坑: Shadow 变量

Go语言的坑: Shadow 变量

[toc]

var client *http.Client
  if tracing {
    client, err := createClientWithTracing()
    if err != nil {
      return err
    }
    log.Println(client)
  } else {
    client, err := createDefaultClient()
    if err != nil {
      return err
    }
    log.Println(client)  }

在上面这段代码中,声明了一个 client 变量,然后使用 tracing 控制变量的初始化,可能是因为没有声明 err 的缘故,使用的是 := 进行初始化,那么会导致外层的 client 变量永远是 nil。这个例子实际上是很容易发生在我们实际的开发中,尤其需要注意。

如果是因为 err 没有初始化的缘故,我们在初始化的时候可以这么做:

var client *http.Client
  var err error
  if tracing {
    client, err = createClientWithTracing() 
  } else {
    ...
  }
    if err != nil { // 防止重复代码
        return err
    }

或者内层的变量声明换一个变量名字,这样就不容易出错了。

我们也可以使用工具分析代码是否有 shadow,先安装一下工具:

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

然后使用 shadow 命令:

go vet -vettool=/path/to/shadow ./main.go
# command-line-arguments
./main.go:15:3: declaration of "client" shadows declaration at line 13
./main.go:21:3: declaration of "client" shadows declaration at line 13
Licensed under CC BY-NC-SA 4.0
Built with Hugo
主题 StackJimmy 设计