首页 >后端开发 >Golang >Go 的 Is() 和 As() 函数如何处理递归错误包装?

Go 的 Is() 和 As() 函数如何处理递归错误包装?

Patricia Arquette
Patricia Arquette原创
2024-12-16 10:52:10691浏览

How Do Go's `Is()` and `As()` Functions Handle Recursive Error Wrapping?

Go 错误:揭开 Is() 和 As() 的神秘面纱

在 Go 中,错误处理对于提供有意义的诊断和分析至关重要。实施强有力的计划。 error 包提供 Is() 和 As() 函数,分别用于确定错误相等性和提取特定细节。一个常见的误解是这些函数支持递归错误包装,从而能够展开多个嵌套错误。

但是,经过仔细检查,标准 fmt.Errorf 函数不提供递归错误包装。这意味着使用 %w 包装错误不允许完全遍历错误链。

为了解决此问题,可以定义自定义错误类型来实现错误接口并实现自己的 Is() 和As() 方法。这允许递归展开多个嵌套错误。

示例:

type customError struct {
    err     error
    wrapped *customError
}

func (c *customError) Error() string {
    if c.err != nil {
        return c.err.Error()
    }
    return "Custom error without cause"
}

func (c *customError) Is(err error) bool {
    if c.err != nil {
        return errors.Is(c.err, err)
    }
    return false
}

func (c *customError) As(target interface{}) bool {
    if c.err != nil {
        return errors.As(c.err, target)
    }
    return false
}

func Wrap(errs ...error) error {
    var rootError *customError
    for i := len(errs) - 1; i >= 0; i-- {
        rootError = &customError{
            err:     errs[i],
            wrapped: rootError,
        }
    }
    return rootError
}

使用此自定义错误类型,您可以轻松包装和展开多个错误并执行递归 Is() 和 As () 检查:

err := Wrap(Err1, Err2, Err3)
fmt.Println(errors.Is(err, Err1)) // true
fmt.Println(errors.Is(err, Err3)) // false

var errType ErrType
errors.As(err, &errType)
fmt.Println(errType) // "my error type"

虽然此自定义实现提供递归错误展开,但有目前,Go 标准库中没有内置类型可以提供开箱即用的此功能。然而,像 github.com/pkg/errors 这样的库提供了额外的错误处理功能,包括递归解包,这可能值得在您自己的项目中考虑。

以上是Go 的 Is() 和 As() 函数如何处理递归错误包装?的详细内容。更多信息请关注PHP中文网其他相关文章!

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