不想Go 错误处理太臃肿,可以参考这个代码设计
最近写了个程序,因为是急活(貌似没有不急的...),所以这个程序又是我东拷一段,西粘一块拼出来的。代码写完了后,感觉这代码屎一样,都快把自己看哭了。真的是在心里边写别骂,先是骂以前做这个项目的人蠢,项目搞的跟屎一样,后来代码跑起来了,顺利交工后,变成了骂我自己蠢,这么写又不是不能用!
又不是不能用
不过在这个过程中,先不提项目里的业务逻辑、接口设计合不合理的事儿,这个我觉得在时间紧,加上人员更迭快的时候,正常人都会能粘就粘,不行了就再包一层,别改出线上问题了就行。有一点我把自己蠢哭的是,Go 的这个错误处理也太TM蠢了,一个程序我写了七八个错误判断,我给你们用伪代码描述一下:
err, file := 接收传文件(文件)
if err != nil {
记日志
返回错误码相应
}
err, fh := 打开上传文件(file)
if err != nil {
记日志
返回错误码相应
}
err, data := 把文件里的行记录解析/转换一下(row)
if err != nil {
记日志
返回错误码相应
}
err, data3 := 调一下第三方接口拿数据
if err != nil {
记日志
返回错误码相应
}
err, data2 := 调一下内部其他服务拿数据
if err != nil {
记日志
返回错误码相应
}
err := 写库
if err != nil {
记日志
返回错误码相应
}
上面这个例子毫不夸张,我相信各位在自己的项目里一定见过,如果你是做业务开发的会更常见。
这里有人肯定会问,Go的错误处理就这样你难道第一天见吗,还能被蠢哭。诶,这不是降本提效后人员少了一半,我们这帮级别没混上去的虚线Leader,这不又开始自己写代码了嘛,以前蠢又蠢不到自己。再加上以前的系统、项目分层、服务隔离整的还凑活,不会像上面这样,在控制层调这么多业务对象,把蠢瓜代码集中在了一起…… 官感马上不一样了。
于是乎我就在思考,有没有什么设计模式什么的,能把这些东西隐藏下去,应该有吧,没有什么是包一层代码解决不了的吧,实在不行就包两层……诶,咋一不小心把设计模式的精髓给说出来了。
Go 优雅处理错误的几种方案
我这几天在网上看了不少说,Go 错误处理的,但基本上都是说怎么自定义包装 error 、传递error 之类的,讲怎么在写 Go 代码时能更优雅更好看的文章比较少,写的最好的是左耳朵耗子老师在自己博客里介绍的两种方式。
一种是用函数式编程的 Closure 把相同的 if err !=nil 之类的代码抽象出来重新定义一个函数,但是这种方式会导致新的问题--在每个函数里都需要引入内部函数和一个 error 变量,所以咱就不多说了,有兴趣的可以去原博文查看。
这里直接介绍另外一种更好的,对项目侵入不是很大的方案给大家。在 Go 语言官方库