您好,登录后才能下订单哦!
本篇内容主要讲解“Golang error使用场景是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Golang error使用场景是什么”吧!
在Go
的编程中, error
的使用场景数不胜数, 主要就是用来处理各种异常情况.
长久以来, 我的使用方式都是这样的:
err := errors.New("fail") if err != nil{ //do somethine... }
简单易懂.
但是, 如果我们的调用链是这样的func1 -> func2 -> func3 -> func4 -> func5
, 此时func5
发生错误, error
逐层向上传递, func1
拿到错误后, 因为缺少堆栈信息, 很难根据error
还原出错场景.
那么, 根据这个问题, 又该如何处理呢? 很简单, 函数拿到error
后, 在其中添加当前上下文信息后再返回不就行了么? 类似于这样:
func func4() error { err := func5() if err != nil { return errors.New(err.Error() + "--func4") } return nil }
这当然可以. 但是上层还可能根据不同的error
进行不同的异常处理, 这样的话, 使用err == SameErr
的判断条件就不好使了.
那么, 如何能够在error
中添加信息的同时, 又不丢失原始error
的信息呢?
其实, 官方已经做好了类似的支持.
在Go
的fmt
库中有这样一个error
:
type wrapError struct { msg string err error } func (e *wrapError) Error() string { return e.msg } func (e *wrapError) Unwrap() error { return e.err }
它提供了一个Error
方法来实现error
接口, 同时还会保存原始的err
信息, 可以通过Unwrap
获得. 这不就是我们需要得么?
官方对其的使用进行了封装, 包含了:
对异常进行包装
判断指定异常是否存在与包装链中
从包装链中提取指定类型的异常
// 对 err 进行包装. // 注意, 占位符必须为 %w, 否则返回的就是一个普通 error err1 := fmt.Errorf("func4: %w", err) // 判断 err1 中是否包含 SameErr 这个错误 // 相当于对所有 error 依次解包并进行 == 的比较 if errors.Is(err1, SameErr) { // 存在 SameErr } // 从 err 中获取指定类型的错误 var sameErr *SameErrStruct if errors.As(err, &sameErr) { // 成功从 err 中获取到 SameErr } // 对error 进行解包, 若失败返回 nil retErr := errors.Unwrap(err1)
翻了翻几个方法的源码都比较简单, 在这里就不细述了.
但是, 这样一层一层将调用信息返回去, 还是有些麻烦, 有没有什么办法, 能够直接将调用栈放进去呢? 或者说, 在Go
中如何获取调用栈呢?
func getStack() { // 获取当前调用栈 pcs := make([]uintptr, 64) pcNum := runtime.Callers(2, pcs) // skip 2 是为了跳过 Callers 及其内部函数 // 调用栈解析 frames := runtime.CallersFrames(pcs[:pcNum]) for frame, more := frames.Next(); more; frame, more = frames.Next() { fmt.Printf("file: %s, line: %d, func: %s\n", frame.File, frame.Line, frame.Function) } }
到此,相信大家对“Golang error使用场景是什么”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。