本文转载自微信公众号《我的脑子是炸鱼》,作者陈建宇。转载本文请联系脑筋急转弯公众号。大家好,我是炸鱼。前段时间,在分享完一文后,与一位朋友进行了深入交流,他分享了他们项目组调整Go错误处理的方式。简单的说,就是在业务代码中用panic来代替“无穷”iferr!=nil。下面就来看看具体怎么做,有什么优缺点,互相切磋一个回合。为什么要替换iferr!=nilGo语言写的太多了,还要处理各种方法声明,麻烦不??方便:err:=foo()iferr!=nil{//dosomething。.returnerr}err:=foo()iferr!=nil{//dosomething..returnerr}err:=foo()iferr!=nil{//dosomething..returnerr}err:=foo()iferr!=nil{//做一点事。.returnerr}以上还是示例代码,比较直白。如果是在工程实践中,还得跳来跳去,在各种包中加上iferr!=nil,比较麻烦,而且还要顾全上下游。其他的我就不多说了,大家可以关注我的公众号看之前的文章。如何替换err!=nil如果你不想写iferr!=nil代码,一种方法是用panic替换它。示例代码如下:funcGetFish(db*sql.DB,namestring)[]string{rows,err:=db.Query("selectnamefromuserswhere`name`=?",name)iferr!=nil{panic(err)}延期。Close()varnames[]stringforrows.Next(){varnamestringerr:=rows.Scan(&name)iferr!=nil{panic(err)}names=append(names,name)}err=rows.Err()iferr!=nil{panic(err)}returnnames}在上面的业务代码中,我们将returnerr的函数return替换为panic的方式。与之关联的下游业务代码自然不需要写iferr!=nil代码:funcmain(){fish1:=GetFish(db,"friedfish")fish2:=GetFish(db,"saltedfish")fish3:=GetFish(db,"touchfish")...}同时转换为panic模式error机制后,我们必须在外层添加recover方法:funcAppRecovery()gin.HandlerFunc{returnfunc(c*gin.Context){deferfunc(){iferr:=recover();err!=nil{if_,ok:=err.(AppErr);ok{//dosomething...}else{panic(err)}}}()}}在每次panic之后,根据它抛出的错误进行断言,判断是否是自定义的AppErr错误类型,如果是,则可以进行一系列的处理动作。否则可以继续panic,丢给顶层Recovery方法处理。这是一个比较完整的panic错误链接处理。优缺点优点方面:整体代码结构看起来比较简洁,只关注实现逻辑。无需关注和编写多余的iferr!=nil错误处理代码。缺点方面:认知负荷的增加,要求每一个参与项目的新老同学都对模型有所了解,需要进行基本的规范或培训。有一定的性能开销,每次发生panic都要进行一次用户态上下文切换。存在一定的风险,一旦恐慌情绪没有恢复,就会引发事故。Go官方并没有推荐它,它违反了panic本身的定义,即混淆了panic和error的概念。综上所述,今天这篇文章给大家分享的是如何使用panic方法处理Go错误。它必须有优点和缺点,需要权衡。
