这篇文章主要介绍“Golang的error处理方法有哪些”,在日常操作中,相信很多人在Golang的error处理方法有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Golang的error处理方法有哪些”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!Golang中的 error 就是一个简单的接口类型。只要实现了这个接口,就可以将其视为一种 error翻看Golang源码,能看到许多类似于下面的这两种error类型缺点:1.让 error 具有二义性error != nil不再意味着一定发生了错误
比如io.Reader返回io.EOF来告知调用者没有更多数据了,然而这又不是一个错误2.在两个包之间创建了依赖如果你使用了io.EOF来检查是否read完所有的数据,那么代码里一定会导入io包一个不错的例子是os.PathError,它的优点是可以附带更多的上下文信息到这里我们可以发现,Golang 的 error 非常简单,然而简单也意味着有时候是不够用的Golang的error一直有两个问题:1.error没有附带file:line信息(也就是没有堆栈信息)比如这种error,鬼知道代码哪一行报了错,Debug时简直要命SERVICE ERROR 2022-03-25T16:32:10.687+0800!!!
Error 1406: Data too long for column ‘content’ at row 12.上层error想附带更多日志信息时,往往会使用fmt.Errorf()
,fmt.Errorf()
会创建一个新的error,底层的error类型就被“吞”掉了为了解决这个问题,我们可以使用github.com/pkg/error包
,使用errors.withStack()方法
将err保
存到withStack对象
也可以使用errors.Wrap(err, "自定义文本")
,额外附带一些自定义的文本信息源码解读:先将err和message包进withMessage对象
,再将withMessage对象
和堆栈信息包进withStack对象
Golang1.13版本借鉴了github.com/pkg/error包
,新增了如下函数,大大增强了 Golang 语言判断 error 类型的能力在1.13版本之前,我们可以用err == targetErr
判断err类型errors.Is()
是其增强版:error 链上的任一err == targetErr
,即return true
例子解读:因为使用errors.WithStack
包装了sqlError
,sqlError
位于error链的底层,上层的error已经不再是sqlError
类型,所以使用==
无法判断出底层的sqlError
源码解读:我们很容易想到其内部调用了err = Unwrap(err)
方法来获取error链中底层的error自定义error类型可以实现Is接口
来自定义error类型判断方法下面我们来看看如何自定义error类型判断:自定义的errNoRows类型
,必须实现Is接口
,才能使用erros.Is()
进行类型判断在1.13版本之前,我们可以用if _,ok := err.(targetErr)
判断err类型errors.As()
是其增强版:error 链上的任一err与targetErr类型相同
,即return true
例子解读:因为使用errors.WithStack
包装了sqlError
,sqlError
位于error链的底层,上层的error已经不再是sqlError
类型,所以使用类型断言无法判断出底层的sqlError
上面讲了如何定义error类型,如何比较error类型,现在我们谈谈如何在大型项目中做好error处理当一个函数返回一个非空error时,应该优先处理error,忽略它的其他返回值在Golang中,对于每个免费云主机域名err,我们应该只处理一次。要么立即处理err(包括记日志等行为),return nil(把错误吞掉)。此时因为把错误做了降级,一定要小心处理函数返回值。比如下面例子json.Marshal(conf)没有return err ,那么在使用buf时一定要小心空指针等错误要么return err,在上层处理err反例:我们应该包装error,但只包装一次上层业务代码建议Wrap error
,但是底层基础Kit库不建议如果底层基础 Kit 库包装了一次,上层业务代码又包装了一次,就重复包装了 error,日志就会打重比如我们常用的sql库
会返回sql.ErrNoRows
这种预定义错误,而不是给我们一个包装过的 error在大型项目中,推荐使用不透明的错误处理(Opaque errors)
:不关心错误类型,只关心error是否为nil好处:耦合小,不需要判断特定错误类型,就不需要导入相关包的依赖。
不过有时候,这种处理error的方式不够用,比如:业务需要对参数异常error类型
做降级处理,打印Warn级别的日志Golang因为代码中无数的if err != nil
被诟病,现在我们看看如何减少if err != nil
这种代码CountLines() 实现了”读取内容的行数”功能可以利用 bufio.scan() 简化 error 的处理:bufio.NewScanner()
返回一个 Scanner
对象,结构体内部包含了 error 类型,调用Err()
方法即可返回封装好的errorGolang源代码中蕴含着大量的优秀设计思想,我们在阅读源码时从中学习,并在实践中得以运用WriteResponse()
函数实现了"构建HttpResponse"
功能利用上面学到的思路,我们可以自己实现一个errWriter
对象,简化对 error 的处理在 Golang 中panic
会导致程序直接退出,是一个致命的错误。建议发生致命的程序错误时才使用 panic,例如索引越界、不可恢复的环境问题、栈溢出等等errors.New()
返回的是errorString对象
的指针,其原因是防止字符串产生碰撞,如果发生碰撞,两个 error 对象会相等。
源码:实践:error1
和error2
的text都是"error"
,但是二者并不相等到此,关于“Golang的error处理方法有哪些”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注百云主机网站,小编会继续努力为大家带来更多实用的文章!
相关推荐: vue的slot-scope/scope属性如何用
这篇文章主要介绍了vue的slot-scope/scope属性如何免费云主机域名用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇vue的slot-scope/scope属性如何用文章都会有所收获,下面我们一起来看看吧。在vue 2…
免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。