Go 语言错误处理的姿势

2021-10-03 17:26:51 +08:00
 nanmu42

各位好。

前段时间看到 v2 上有个帖子,询问如何在 Go 中为错误加上堆栈,我以前也为类似的问题困扰过,后来找到了 pkg/errors ,再后来官方库有了 fmt.Errorf() ,我把这个小小经验写了下来,希望能抛砖引玉,欢迎各位交流拍砖。

在这篇文章中,我们将区分错误( error )和异常( panic ),讨论什么样的错误是“好”的(容易检查和排错),介绍一种让错误变“好”的常用方式(fmt.Errorf())。

谢谢。

4843 次点击
所在节点    Go 编程语言
51 条回复
XTTX
2021-10-03 19:48:54 +08:00
func ReadCache(city string) (weather string, err error) 这种 return 方式不是特别的推荐。 比较难读
js2854
2021-10-03 20:12:16 +08:00
@XTTX 这不是 go 的常见做法么,还能写出啥花样?
darksword21
2021-10-03 20:16:41 +08:00
@XTTX 我也不喜欢这样,而且有时候会有些问题
iyear
2021-10-03 21:27:57 +08:00
@js2854 #2 不要给返回值名字,这很容易写出 bug
Hanggi
2021-10-03 22:10:27 +08:00
这种写法本身没有什么问题,就是相当于在顶部声明了变量。
只不过这种写法可以直接 return,在大的函数里可能不清楚到底 return 了什么。

这时候只要把返回值写进去就可以了。
nanmu42
2021-10-03 23:14:51 +08:00
裸返回和一般的返回是等效的,优势是可以少写一点东西。

劣势是有时确实容易写出 bug, 这时一般推荐用上包含 ineffetient assign 的静态分析 linter,可以避免翻车。
XTTX
2021-10-03 23:24:18 +08:00
@js2854 这不是一种常见的作法。 自己写的容易忘记,何况让别人读。
SorcererXW
2021-10-04 05:54:10 +08:00
@XTTX
感觉这种方式主要问题可能不是难读,而是容易发生变量作用域覆盖或者忘记返回具体值,引入潜在的 BUG 。但是如果一个函数返回结果非常复杂,使用返回值命名可以降低理解成本。可以写成这样 func ReadCache(city string) (_weather string, _err error),避免直接对 _xxx 赋值,而是强制使用 return 。
XTTX
2021-10-04 08:57:01 +08:00
@SorcererXW standard libs 都用一种方式是有原因的。
js2854
2021-10-04 11:27:41 +08:00
@iyear 不能一棍子打死,短小的代码这样写有时还是能省略无用的声明的
@XTTX 容不容易出 bug 是另一回事,怎么就难读了?
lesismal
2021-10-04 12:03:18 +08:00
@XTTX #9 go 源码里这种还是挺常见的
XTTX
2021-10-04 12:17:45 +08:00
https://tour.golang.org/basics/7 自己看吧。我不懂怎么解释这么明显的东西。
lesismal
2021-10-04 12:31:18 +08:00
lesismal
2021-10-04 12:32:27 +08:00
@XTTX 另外,虽然源码里算常见,但我个人也不喜欢这种写法,自己代码里基本不用。
lesismal
2021-10-04 12:38:48 +08:00
@XTTX tour 里说的是建议性的并不是说 std 里没有,我第一次是回复你 #9 "standard libs 都用一种方式"
ZSeptember
2021-10-04 17:22:20 +08:00
你这文章真是写了个寂寞。。
标题叫错误处理,正文没有任何错误处理的内容。。
可能对错误处理有一些误解,使用 fmt 添加错误上下文的错误,是无法处理的。只能打个日志,然后方便排查问题。
错误处理最重要的是错误识别,也就是需要用到 Is,As,Unwrap 系列方法,识别已知的错误,然后根据情况处理,未知的错误继续往外抛。
要做错误识别,需要支持错误继承,嵌套什么的,pkg/errors 也并不只是添加堆栈上下文,也是稍微支持了错误继承。
Linxing
2021-10-04 18:09:15 +08:00
@XTTX 同意 这种写法给看代码的人带来挺大的心智负担 变量声明越接近变量使用的地方最好
xsen
2021-10-04 20:10:47 +08:00
@XTTX
@Linxing
有心智负担,是因为还没习惯;习惯成自然,习惯之后也没什么事情
XTTX
2021-10-05 00:35:22 +08:00
@lesismal 大哥你自己不看一下你贴了些什么吗? 里面的源码用了 named return, 但是别人用 naked return 了吗?我是真的不想回这个话题了, 自己了解清楚再出来杠。 我的上个回复也不是针对你的, 我回复的是 js285 什么的
XTTX
2021-10-05 00:38:30 +08:00
naked return 除了写的时候剩下 2 秒钟,根本没有其他的好处。naked return 除了 c++, 其他语言应该没有。不熟悉 go 的人会误以为什么都没有 return. 成熟的团队也不会让你短的 func 用 naked return, 长的用正常 return.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/805771

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX