【Golang源码阅读】errors/wrap.go

网友投稿 242 2022-10-24

【Golang源码阅读】errors/wrap.go

// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package errors import ( "internal/reflectlite" ) // Unwrap 返回对 err 调用 Unwrap 方法的结果,如果 err 的类型包含返回错误的 Unwrap 方法。否则,Unwrap 返回 nil。 func Unwrap(err error) error { u, ok := err.(interface { Unwrap() error }) if !ok { return nil } return u.Unwrap() } // Is 报告 err 链中的任何错误是否与目标匹配。 // // 该链由 err 本身和通过重复调用 Unwrap 获得的错误序列组成。 // // 如果错误等于该目标,或者如果它实现了 Is(error) bool 方法使得 Is(target) 返回 true,则认为错误与该目标匹配。 // // 错误类型可能提供 Is 方法,因此可以将其视为等同于现有错误。 例如,如果 MyError 定义了 // // func (m MyError) Is(target error) bool { return target == fs.ErrExist } // // 然后 Is(MyError{}, fs.ErrExist) 返回 true。 有关标准库中的示例,请参见 syscall.Errno.Is。 func Is(err, target error) bool { if target == nil { return err == target } isComparable := reflectlite.TypeOf(target).Comparable() for { if isComparable && err == target { return true } if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) { return true } // TODO: 考虑支持 target.Is(err)。 这将允许用户定义谓词,但也可能允许处理草率的 API,从而更容易摆脱它们。 if err = Unwrap(err); err == nil { return false } } } // As 查找与目标匹配的 err 链中的第一个错误,如果是,则将目标设置为该错误值并返回 true。 否则,它返回 false。 // // 该链由 err 本身和通过重复调用 Unwrap 获得的错误序列组成。 // // 如果错误的具体值可分配给目标指向的值,或者错误具有方法 As(interface{}) bool 使得 As(target) 返回 true,则错误与目标匹配。 // 在后一种情况下,As 方法负责设置目标。 // // 错误类型可能提供 As 方法,因此可以将其视为不同的错误类型。 // // 如果目标不是指向实现错误的类型或任何接口类型的非空指针,则作为panics。 func As(err error, target interface{}) bool { if target == nil { panic("errors: target cannot be nil") } val := reflectlite.ValueOf(target) typ := val.Type() if typ.Kind() != reflectlite.Ptr || val.IsNil() { panic("errors: target must be a non-nil pointer") } if e := typ.Elem(); e.Kind() != reflectlite.Interface && !e.Implements(errorType) { panic("errors: *target must be interface or implement error") } targetType := typ.Elem() for err != nil { if reflectlite.TypeOf(err).AssignableTo(targetType) { val.Elem().Set(reflectlite.ValueOf(err)) return true } if x, ok := err.(interface{ As(interface{}) bool }); ok && x.As(target) { return true } err = Unwrap(err) } return false } var errorType = reflectlite.TypeOf((*error)(nil)).Elem()

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Dcoker 容器命令
下一篇:常见的固态硬盘接口有哪些
相关文章

 发表评论

暂时没有评论,来抢沙发吧~