你使用的Go版本是什么( go version
)?
$ go version
go version go1.16 linux/amd64
这个问题在最新版本的发布中是否重现?
是的
你正在使用什么操作系统和处理器架构( go env
)?
go env
输出
$ docker run --rm golang:1.16 go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.16"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build813662227=/tmp/go-build -gno-record-gcc-switches"
GOROOT/bin/go version: go version go1.16 linux/amd64
GOROOT/bin/go tool compile -V: compile version go1.16
uname -sr: Linux 4.19.121-linuxkit
/lib/x86_64-linux-gnu/libc.so.6: GNU C Library (Debian GLIBC 2.28-10) stable release version 2.28.
你做了什么?
在包含以下内容的包上运行了 go vet
:
package vetexample
import "fmt"
func BuggyCode() error {
failf := func(format string, args ...interface{}) error {
return fmt.Errorf(format, args)
}
return failf("%v")
}
你期望看到什么?
go vet
在 failf
调用中捕获格式字符串和参数列表之间的不匹配。
你看到了什么?
该包通过了审核。
这种将printf家族函数 Package 在闭包中的模式也可以在Go源代码中找到。
go/src/cmd/go/internal/modfetch/coderepo.go
第324行到第332行的 2f0da6d
| | invalidf:=func(formatstring, args...interface{}) error { |
| | return&module.ModuleError{ |
| | Path: r.modPath, |
| | Err: &module.InvalidVersionError{ |
| | Version: info2.Version, |
| | Err: fmt.Errorf(format, args...), |
| | }, |
| | } |
| | } |
虽然我不太希望 go vet
能够一般地分析一个函数值是否 Package (或是)一个printf家族函数,但它是否可行去分析更有限的情况,即一个作用域为函数的局部变量被赋值为一个函数字面量值?
1条答案
按热度按时间6tr1vspr1#
go vet
具有识别failf
为 printf Package 器的能力。据我理解,它没有识别它的原因是因为failf
不是一个顶级函数。也就是说,failf
被认为不是一个 printf Package 器,因为它是一个可以改变内容的变量。go vet
可以扩展以涵盖本地定义的函数,如failf
,然后在这些failf
(例如,仅在封闭函数中调用,而没有其他地方调用)的情况下检查输入格式问题(例如,作为参数传递或分配值)。问题是,刚刚描述的代码模式有多普遍?我们是否可以通过某种方式获取数据来证明上述扩展的合理性?