使用错误变量作为包级变量与全局变量

Using an error variable as package-level vs global variable

我正在使用 Go 语言编写一个使用自定义错误变量的函数,例如

func readEnv() (map[string]string, error) {
    var ErrConfig = errors.New("Configuration Error: Variables starting with the right prefix are not even")

if this {
  return nil, ErrConfig
}

我将其声明为本地 var 以避免将其声明为不推荐的包级 var(如果我没记错的话,将其标记为 linter 的问题)

当我想对这个 fxn 进行单元测试并且还想测试错误路径时,问题就出现了(在这种情况下,fxn 应该 return 上面的错误但是无法访问。)。现在,我能想到的解决这个问题的唯一方法是在我的 table 测试中重新声明这个变量。

哪种方法正确?将 ErrConfig 声明为包级变量或仅在单元测试 fxn 中重新声明它?

readEnv() 的调用者有什么关系吗 return?

如果没关系,你的测试也不应该关心,只要检查 returned 错误是 nil 还是不是。

如果这很重要,在您当前的解决方案中,调用者在测试中不能比您做得更好。如果它很重要并且客户应该能够分辨出来,那么您必须导出某种机制来测试/检查 returned 错误。

一个解决方案是将 ErrConfig 移动到包级别变量。这是被接受的,也在标准库中使用了很多地方,例如io.EOF, io.ErrClosedPipe.

但这不是唯一的解决方案。您可以使 Errconfig 未导出(例如 errConfig),并提供导出函数来测试错误,例如:

var errConfig = errors.New("Configuration Error: Variables starting...")

func IsErrConfig(err error ) bool {
    return err == errConfig
}

这在标准库中的许多地方也有使用,例如os.IsExist(), os.IsNotExist()

您还可以使 returned 错误实现导出的接口,调用者可以使用类型断言检查 returned 错误是否实现了该接口,从而为 [=36] 提供额外的功能=]编辑错误。