很实用:它不能防止代码中所有可能的 nil panic,但能捕获我们在生产中观察到的大部分潜在 nil panic,从而使 NilAway 在实用性和构建时间开销之间保持良好的平衡。
$ go install go.uber.org/nilaway/cmd/nilaway@latestnilaway 能够遍历扫描目录下的所有文件:
$ nilaway ./...也可以扫描单独的文件:
$ nilaway demo.go注:本文安装 @latest 的原因,是因为写此文时 nilaway 还在积极开发阶段,暂时没有发布正式的版本。如果后续有正式版本,也可以指定相应版本号。
// 堆代码 duidaima.com var p *P if someCondition { p = &P{} } print(p.f) // nilness reports NO error here, but NilAway does.在上述代码中,当 someCondition 变量值为 true 时,才会初始化结构体 P。如果 someCondition 变量为 false 时,就会出现空指针调用的 panic 问题。
go.uber.org/example.go:12:9: error: Potential nil panic detected. Observed nil flow from source to dereference point: -> go.uber.org/example.go:12:9: unassigned variable `p` accessed field `f`如果我们增加 if p != nil 来做防御,报告的错误就会消失。
func foo() *int { return nil } func bar() { print(*foo()) } func main() { // 堆代码 duidaima.com bar() // nilness reports NO error here, but NilAway does. }函数 foo 返回了一个 nil 指针,该指针在函数 bar 中被直接取消引用,导致每当调用函数 bar 时都会出现 panic 问题。
➜ ~ nilaway demo.go /Users/eddycjy/demo.go:7:9: error: Potential nil panic detected. Observed nil flow from source to dereference point: -> eddycjy/demo.go:4:9: literal `nil` returned from `foo()` in position 0 -> eddycjy/demo.go:7:9: result 0 of `foo()` dereferenced上面的例子虽然是同 package 内跨函数的问题识别,但实际上该工具也嫩能够分析跨 package 的调用。