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中文网其他相关文章!