multierr 用于 Go:合并并处理多个错误
\n在 Go 中,错误处理是开发中明确且不可或缺的一部分。然而,经常会出现这样的情况:在执行一个操作的过程中,可能发生不止一个错误,而是多个错误。例如,在批量处理文件、验证复杂数据结构或执行并行任务时。标准库 errors 仅允许一次处理一个错误,这使得收集和分析所有发生的故障变得复杂。
来自 Uber 公司(没错,就是创建了 zap 和 fx 的那家公司)的 multierr 库优雅且高效地解决了这个问题。它提供了一个简单的 API,用于将多个独立的错误合并成一个复合错误。这允许保留所有故障的上下文,而不会丢失信息,并在一个地方处理它们。与手动创建错误切片不同,multierr 提供了方便的函数用于组合、检查错误是否存在以及遍历它们。
该库的基本理念是 简单和性能。它在不必要的情况下不会在堆上创建额外的分配,并努力最小化开销。multierr 非常适合需要从不同来源(例如,从 goroutine)收集错误并将它们作为单个结果返回的情况,然后可以使用标准的 if err != nil 来检查是否存在错误。
安装
\n使用标准命令 go get 安装该库。请确保您已安装 Go 1.13 或更高版本(以支持 errors.Is 和 errors.As)。
go get go.uber.org/multierr\n 执行命令后,该库将被添加到您的 go.mod 文件中。导入方式如下:
import "go.uber.org/multierr"\n\n 快速入门:最小示例
\n让我们看一个最简单的例子:我们有两个可能返回错误的函数。我们希望执行这两个函数,如果至少有一个执行失败,则返回一个总错误。
\npackage main\n\nimport (\n "errors"\n "fmt"\n "go.uber.org/multierr"\n)\n\nfunc doSomething() error {\n return errors.New("第一个错误")\n}\n\nfunc doAnotherThing() error {\n return errors.New("第二个错误")\n}\n\nfunc main() {\n var err error\n \n // 执行第一个操作\n err = multierr.Append(err, doSomething())\n // 执行第二个操作\n err = multierr.Append(err, doAnotherThing())\n \n if err != nil {\n fmt.Println("发生了错误:")\n // 输出所有错误,用换行符分隔\n for _, e := range multierr.Errors(err) {\n fmt.Println("-", e)\n }\n }\n}\n 在这个例子中,multierr.Append 将一个错误添加到现有错误中。如果 err 为 nil,该函数仅返回新错误。结果,我们得到一个复合错误,可以使用 multierr.Errors 将其分解为各个部分。
主要函数和方法
\nmultierr 库提供了一组虽小但功能强大的函数。让我们详细看看每一个。
1. multierr.Append
\n 签名: func Append(left error, right error) error
描述: 这是合并两个错误的主要函数。如果两个错误都为 nil,则返回 nil。如果其中一个为 nil,则返回另一个。如果两者都不为 nil,则它们被合并成一个复合错误。
图书馆中也有