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

Go 如何检查errors.Errorf()中的类型错误?,go,Go,对字符串格式化函数(如fmt.Printf)的调用似乎是Go编译器的一个弱点。我最终发现了很多bug(在重构后使用了错误的格式化程序,忘记了包含所有参数),这些bug只在运行时才会暴露出来。所以每次我写这些东西的时候,我都得努力眯着眼睛 我今天做了一些研究,发现了go tool vet,它似乎适用于fmt.Printf,但它不能捕捉errors.Errorf中的错误(见下文) 是否有一个类似于go tool vet的程序,可以捕获errors.Errorf()中的字符串格式错误?还有,就我自己的

对字符串格式化函数(如fmt.Printf)的调用似乎是Go编译器的一个弱点。我最终发现了很多bug(在重构后使用了错误的格式化程序,忘记了包含所有参数),这些bug只在运行时才会暴露出来。所以每次我写这些东西的时候,我都得努力眯着眼睛

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


是否有一个类似于go tool vet的程序,可以捕获errors.Errorf()中的字符串格式错误?还有,就我自己的理解,为什么这是一个如此困难的问题?对于Go编译器来说,捕获字符串格式类型错误似乎并不比捕获任何其他类型的类型错误更困难。

您可以告诉
Go-vet
要检查哪些函数(比较):

要做到更好并不容易,原因有很多:

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

啊,-printfuncs正是我想要的。一个澄清:您所说的“格式字符串是运行时值”是什么意思?似乎它们可以像其他任何东西一样在编译时进行分析(因为参数的类型是已知的)。我试图澄清为什么这很困难,现在它有意义吗?啊,好吧,你是说Printf的第一种艺术可以是一个在编译时其值未知的变量。在大多数情况下,第一个参数似乎是一个常量字符串,但我想Go不想消除这些情况的歧义?
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)
}
$ 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