Go 的错误处理函数 Is() 和 As() 声明是递归的,能够解开多个嵌套错误。但是,尚不清楚是否存在实现错误接口并支持此递归功能而不会出现问题的内置类型。
有缺陷的自定义实现
尝试创建自定义错误类型经常遇到问题,因为 Go 中的错误是按地址进行比较的。将错误包装为指针的自定义类型会导致意外行为,例如修改后的父错误会影响后续包装。
可行的解决方案
更强大的解决方案涉及创建一个新的错误类型,errorChain。该类型包含一个 err 字段来存储当前错误,以及一个 next 字段来引用链中的下一个错误。此外,它还实现了 Is() 和 As() 方法来促进递归错误展开。
包装和展开
Wrap() 函数接受多个错误,创建一个 errorChain 对象,并将它们链接在一起。 Unwrap() 函数遍历链,返回序列中的下一个错误。
示例
使用 errorChain 类型,您可以递归地包装和解开错误:
type errorChain struct { err error next *errorChain } func Wrap(errs ...error) error { out := errorChain{err: errs[0]} n := &out for _, err := range errs[1:] { n.next = &errorChain{err: err} n = n.next } return out } func (c errorChain) Is(err error) bool { return c.err == err } func (c errorChain) As(target any) bool { return errors.As(c.err, target) }
游乐场: https://go.dev/play/p/6BYGgIb728k
以上是Go 的 Is() 和 As() 真的提供递归错误解包吗?的详细内容。更多信息请关注PHP中文网其他相关文章!