如何检查errors.Errorf()中的类型错误?

时间:2018-08-20 15:24:21

标签: go

对诸如fmt.Printf之类的字符串格式函数的调用对于Go编译器似乎是一个弱点。我最终遇到了许多错误(重构后使用了错误的格式化程序,忘记了包含所有参数),这些错误只能在运行时显示出来。因此,每次写这些文章之一时,我都不得不斜视一下。

我今天做了一些研究,发现了go tool vet,它似乎适用于fmt.Printf,但是它不能捕获error.Errorf中的错误(见下文)。

import "github.com/pkg/errors"

func ReturnError(s string, i int) error {
    // Swap %d and %s, and forget to include the second argument
    return errors.Errorf("invalid arguments %d and %s", s)
}

是否有go tool vet的类似物,可以捕获error.Errorf()中的字符串格式错误?另外,以我自己的理解,为什么这是一个难题?对于Go编译器来说,捕获字符串格式的类型错误似乎比其他任何类型的错误都困难。

1 个答案:

答案 0 :(得分:4)

您可以告诉go vet要检查哪些功能(比较godoc.org/cmd/vet):

$ cat x.go
package main

import "github.com/pkg/errors"

func ReturnError(s string, i int) error {
    // Swap %d and %s, and forget to include the second argument
    return errors.Errorf("invalid arguments %d and %s", s)
}
$ go vet x.go 
$ go vet -printfuncs Errorf x.go 
# command-line-arguments
./x.go:7: Errorf format %d has arg s of wrong type string

要做到这一点并不容易,原因有很多:

  • 格式字符串是运行时值:您可以调用fmt.Sprintf(prefix + "%s", ...)。因此不可能在编译时捕获所有无效的格式字符串。
  • 格式字符串没有特殊类型。因此,仅通过查看函数定义,编译器就无法轻易确定某些函数(在这种情况下为errors.Errorf)期望其参数的行为类似于fmt.Printf