Go 语言错误处理的姿势

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

各位好。

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

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

谢谢。

4844 次点击
所在节点    Go 编程语言
51 条回复
xuzhzzz
2021-10-06 17:11:51 +08:00
楼歪到姥姥家了
chaleaoch
2021-10-06 17:38:59 +08:00
如果没有裸返回, 如何实现 recover 修改函数返回值? 请教?
XTTX
2021-10-06 19:40:44 +08:00
@lesismal 你 jjyy 那么多只为打脸我一句“standard lib”都不用 naked return. 然后还举个例子, 例子里还是反向证明大部分都不用 naked return. 你也太搞笑了,是你去翻我的“黑史”。 我可没有去翻你的贴子。
XTTX
2021-10-06 19:42:19 +08:00
“我也赞成 named/naked 不好, 但是我抓到了对方论点里一点不严谨的地方, 我要去打他的脸,打不成我就去翻他以前的贴子,去黑他,然后我再装圣母。” 这是杠精行为, 我不回复了。 你慢慢品。
chaleaoch
2021-10-06 20:14:02 +08:00
@XTTX 大佬请教问题, 如何实现 recover 修改函数返回值?
lesismal
2021-10-06 20:38:33 +08:00
@XTTX 我已经解释过两次了,不是翻你黑史,而是那个帖子先有了印象所以加上这个帖,但凡你前面仔细看下我在说哪个点,我至于掰扯这么多、提那个帖子?因为你不把观点表达清楚、回复之前那个哥们也没 at 别人,回复我也不看我是在说哪个点,所以才会联想到你之前帖子、聊技术太随意了。

另外,也别上纲上线的弄好像我人身攻击你一样,这两个帖子你要是不那么随意,也不会有这么多互喷。我抱怨下就成了我故意攻击你?那你随意在先、并且我都回复了那么多似乎直到上一条你才看懂我在杠什么,那你就尊重别人了?麻烦你能不能讨论的时候认真点先?

再说,技术的事情,就事论事,该严谨的地方,怎么就不能杠精了?十几年前,或者至少八九年前,技术群还没那么多,好多人都是论坛上交流,一个技术问题,一群人争论得没完没了,随便盖出几十几百楼,就比如源码的事情,尤其是底层的一些、源码级别相关的,大家都非常重视,一丁点细微差别都可能是天差地别,经常都能杠得各自在各自电脑前面红耳赤,但是技术的问题,杠完了大家都更清楚了,也不会因为杠技术本身而觉得彼此伤害了。反倒是遇到随便拿来什么就信口开河满嘴跑火车聊技术的会让大家郁闷。技术的事情,从论坛到工作到开源,包括内核社区,即便不是三天两头,也是隔三差五就会有杠的事情发生,认真杠一些事情才争论的清楚,不信你去翻翻 linus 大神历史。

说我杠精行为就杠精行为吧,我承认,对于技术,我确实比较杠。
但是,杠精就不对了?专业领域的杠,别人还夸你认真钻研呢,如果都不杠了,高级的科学家、工程师、设计师各种估计都得绝种。都不杠了,小白错误言论满天飞,更多小白被带歪。技术不是娱乐圈,虽然拿娱乐心态聊技术不违法并且是你的自由,但既然你不认真了,也麻烦你不要怪罪别人认真对待技术的人。

如果你觉得就这么一句"standard lib"无关大雅无关紧要,那好,你继续随意吧。你可以自己回顾看下,这两个帖子你对技术的点是不是不够认真,这个帖子提到源码相关的,我猜测你没有怎么研究过。如果没研究过,就没必要随口就说关于它的事情、对更多小白会造成误导。

并且再强调一次,我是先看到的那个帖子然后才注意到这个帖子,不要以为别人有心情故意去黑你,你没那么重要,我也没那么重要。聊技术,就按技术论技术完事了,
我提那个帖子只是说你不认真,但是反过来给我扣的帽子是我搞人身攻击,想问下,到底谁在人身攻击谁?

这两天这个帖子说太多了,浪费了自己时间,也浪费了大家的时间。抱歉了各位,以后我尽量忍住、少回帖。
如果这种行为不好,站长封我我也认,确实心境还够,需要继续修炼学会忍耐与安静。
lesismal
2021-10-06 20:42:06 +08:00
#46 更正结尾处:确实心境还不够,少打了个“不”
Mitt
2021-10-07 01:12:57 +08:00
func FindWeather(city string) (weather string, err error) {
weather, err := ReadCache(city)
if err != nil {
err = fmt.Errorf("reading cache: %w", err)
return
}

if weather != "" {
// cache hit
return
}

// cache missed, query for data source and update cache
// ...
}

虽是这么说,但你这个 Example 就已经有问题了吧,weather 和 err 作用域变了导致裸返回的都是空值
nanmu42
2021-10-07 09:12:14 +08:00
@Mitt 囧,我第二行写错了,:=应为=,我今天改下,谢谢提醒。
作用域应该是没变,上面这句我这么写编译不过去,因为:=左值没有新变量,伪代码大意了。
XTTX
2021-10-08 23:48:49 +08:00
@lesismal 我这辈子都没有碰到有人为我写那么长的文章的人,我谢谢您。
lesismal
2021-10-09 13:37:11 +08:00
@XTTX 不客气。国庆结束了,好好写代码持续输出。

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

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

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

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

© 2021 V2EX