Go语言 关于go error处理风格的一些讨论和个人观点(上)

abv123456789 · · 1126 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

原创文章,转载请注明出处:服务器非业余研究-sunface

 

最近看谷歌go group里面有很多讨论go error处理风格的问题,颇有启发,现在跟大家分享一下,首先请看一个提问:

Hi folks,


When I look at a lot of go code, I see the following pattern:
//当我看了许多go代码后,我发现了以下模式

x, err := foo()
if err != nil {
return err
}

y, err := bar(x)
if err != nil {
return err
}

z, err := baz(y)
if err != nil {
return err
}

// do something w/ z

return nil

This is cool, but comes off as a bit verbose. I've been using the following as a replacement, which I think is a bit nicer:
//上段代码很cool,但是表现的有点冗余,我已经用以下一种error机制作为替代,我认为我的更好

var (
x, y, z T
err      error 

x, err = foo()

if err == nil {
y, err = bar(x)
}

if err == nil {
z, err = baz(y)
}
 
if err == nil { 
// do something w/ z
}

return err 

 
//出于好奇,请问有人用过我这种风格然后有发现过缺点吗?或者这种风格并不好?虽然我认为很好

Just curious, has anyone else used this sort of thing and found a pitfall? Or perhaps has an opinion as to why it isn't actually nice? I think it's nice =].

 

看了上面两种错误处理风格,大家应该已经看出了部分端倪:第一种是比较传统的error处理方式,第二种是作者认为比较创新的error处理方式。先不说第一种的优缺点,

第二种首先在开头设置了所有接收error的变量,然后后面的error处理方式是环环相扣,冗余度非常之高,且直到最后才return,也就是说如果代码够长,那你得看完中间所有的处理过程,在这里你只有读完了整段代码才知道foo()产生的错误到底是怎么处理的。

 

然后一个评论中提出了一种个人觉得不错的风格:

  value,err :=  bar()

  if err != nil {

        goto handleError

  }

.

.

.

.

  handleError:

        return err

 

在这种风格中不需要去知道goto和label中间的代码,可以直接进行错误处理并返回,因此代码简洁、可读性强、性能高且冗余度低。

还有一个评论提出了一种很特别的风格:

if x, err := foo(); err != nil {
   return err
} else if y, err := bar(x); err != nil {
   return err
} else if z, err := baz(y); err != nil {
   return err
} else {
   // do something w/ x,y,z

   return nil
}

这种写法的代码比较简洁,return的地方一眼便可得知。

 

下面这种风格可以节省大量的if语句

func checkErr( err error) {

     if  err != nil {

                    //deal error here

     }

}

func main() {

     ting,err := whatever()

     checkErr(err)

}

下面再说说我个人对提问中第二段代码的看法,主要有3点:

     1.在第二段代码中,所有的有意义的代码都是环环相扣,每一个if和return都要记在脑袋里,具体可以看下这篇文章:代码的嵌套——各种状态的组合。在第一段代码中所有的错误处理都是在产生错误代码的下面,很容易发现什么代码导致了某个错误,而且在那些if代码块之后,你不需要担心之前的x,y,z,因为它们都是合法的。但是在第二段代码中,永远不能知道x,y,z是否合法,每次都得继续验证前面的值。

     2.因为第二段代码的错误处理和返回方式(环环相扣),我们就无法得知error的具体位置,唯一能做的就是彻底放弃然后无奈的说一句“代码有BUG了”,仅此而已。

     3.每次你往第二段代码的函数增加新的代码的时候,都要放在一个if代码快中。相反在第一段代码中,就不需要,因为只有错误处理在if中,其他的都在外部处理

 

这里只是一个简单的抛砖引玉,希望大家能发表下平常项目中使用的错误处理机制,一起讨论。


有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:abv123456789

查看原文:Go语言 关于go error处理风格的一些讨论和个人观点(上)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1126 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传