首页 >后端开发 >Golang >Go 的 `errors.Is` 和 `errors.As` 支持递归错误包装吗?

Go 的 `errors.Is` 和 `errors.As` 支持递归错误包装吗?

Patricia Arquette
Patricia Arquette原创
2024-12-14 19:23:10536浏览

Does Go's `errors.Is` and `errors.As` Support Recursive Error Wrapping?

Go 中的递归错误包装

Go 的错误处理机制提供了 Is() 和 As() 等方法来进行错误检查。然而,通常假设这些方法支持递归错误包装。这并不完全正确。

将 fmt.Errorf 与 %w 动词一起使用仅允许浅层错误包装。要实现真正的递归,需要自定义错误类型。

通常,自定义错误类型将包含指向已包装错误的指针以及解包它的方法。然而,简单地以这种方式包装错误会带来问题。如果多个包装错误共享同一个指针,则错误比较将失败,因为 Go 错误是按地址进行比较的。

解决方案是在自定义错误类型中实现 Is() 和 As() 方法。这些方法应该比较嵌入的错误而不是自定义类型本身,从而允许完全递归错误包装而无需基于地址的问题。

例如,以下是支持递归包装的错误类型的简化版本:

type errorChain struct {
    err  error
    next *errorChain
}

func (c errorChain) Is(err error) bool { return errors.Is(c.err, err) }
func (c errorChain) As(target any) bool { return errors.As(c.err, target) }
func (c errorChain) Unwrap() error  { return c.next }

此错误类型可用于根据需要包装错误,从而允许使用 Is() 和 As() 进行完整的错误检查。

以上是Go 的 `errors.Is` 和 `errors.As` 支持递归错误包装吗?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn