Go语言 关于go error处理风格的一些讨论和个人观点(上)
原创文章。转载请注明出处:server非业余研究-sunface
近期看谷歌go group里面有非常多讨论go error处理风格的问题,颇有启示。如今跟大家分享一下。首先请看一个提问:
Hi folks,
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
var (x, y, z Terr 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
//出于好奇。请问有人用过我这样的风格然后有发现过缺点吗?或者这样的风格并不好?尽管我觉得非常好
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都要记在脑袋里,详细能够看下这篇文章:代码的嵌套——各种状态的组合。在第一段代码中全部的错误处理都是在产生错误代码的以下,非常easy发现什么代码导致了某个错误。并且在那些if代码块之后。你不须要操心之前的x,y,z。由于它们都是合法的。可是在第二段代码中,永远不能知道x,y,z是否合法,每次都得继续验证前面的值。
2.由于第二段代码的错误处理和返回方式(环环相扣),我们就无法得知error的详细位置,唯一能做的就是彻底放弃然后无奈的说一句“代码有BUG了”,仅此而已。
3.每次你往第二段代码的函数添加新的代码的时候,都要放在一个if代码快中。相反在第一段代码中,就不须要,由于仅仅有错误处理在if中。其它的都在外部处理
这里仅仅是一个简单的抛砖引玉。希望大家能发表下寻常项目中使用的错误处理机制,一起讨论。
最新文章
- 【转】个人对JQuery Proxy()函数的理解
- adb_亮屏
- Android闹钟【复杂版】
- java中访问mysql数据库中的表结构信息
- 使用netbeans 搭建 JSF+SPRING 框架
- PHP学习笔记1.1——date()函数的多种用法,取出各种不同格式的时间,非常全面
- WCF/WPF公司内部订餐程序开发
- hdu 5877 线段树(2016 ACM/ICPC Asia Regional Dalian Online)
- 字节转化为结构体BytesToStruct
- 三种bean创建方式
- Tracing Memory access of an oracle process : Intel PinTools
- SpringBoot注解大全(转)
- 改BUG方法
- mac nginx compile
- highchart 柱状图,列宽自适应(x轴是时间的特殊情况)
- js-ES6学习笔记-数组的扩展
- EditText: 自定义EditText 触摸时无法获取焦点
- php使用正则函数使用详解
- lintcode-419-罗马数字转整数
- a=b=c 连等赋值的分析
热门文章
- d3.js入门1:安装配置
- 部署ASP.NET MVC项目
- SpringMVC入门二: 1规范结构, 2简单整合MyBatis
- HDU 1025 DP + 二分
- 17.1.1.4 Obtaining the Replication Master Binary Log Coordinates 获取复制Master Binary Log的坐标:
- [置顶] C++ sizeof实例详解
- Sqlite ContentProvider Loader 上下文 对话框
- 关于C++的子类指针指向父类
- Qt核心剖析: moc
- android在view.requestFocus(0)返回false的解决办法