
起因是看到 https://v2ex.com/t/1128449?p=1#reply41 写了
"相比之下 if err != nil 95%的时候都很不优雅"
好像我也看到很多吐槽 Go 错误处理语法的, 以下错误处理策略摘录自<<The Go Programming Language>> :
有无更优雅的方式能够实现上面的处理策略?
已知的两种:
try except finally 除了实现 1 (上抛)优雅点, 剩下的也没看出多大优势,而且错误发生点和处理点不在同一处,这就注定需要额外的代码来重构上下文, 比如,打开 file1, 然后 file2, 但在打开第 file2 时发生错误,处理的时候得先判定是打开哪个文件出错了,再执行相应错误处理和回滚操作。 1 Ayanokouji 214 天前 我之前发的帖子,有不少评论的解决方案可以参考。 /t/1101542 |
2 PTLin 214 天前 你先把这一百多个被毙了的提案看一下吧,可以说 99%的人能想到的方法里面都有。 https://github.com/golang/go/issues?q=label:error-handling |
4 pike0002 214 天前 |
5 Subilan 214 天前 via iPhone 我觉得最难顶的还是频繁多次错误处理的场景,err 变量不能重定义,要么事先专门声明一个,要么专门为每一个错误单独起个名字来定义。有更好的办法吗? |
6 vczyh 214 天前 就用 err.nn 吧,别的越用越麻烦,实在不行就换语言吧 |
7 vczyh 214 天前 |
10 vczyh 214 天前 @Subilan 我一般这么写: https://imgur.com/a/x4qtu9A |
11 aloxaf 214 天前 > 还有 Optional 一类的,和 if 没太大区别,只不过前者在语法上做了强制(不检查错误,不能拿到结果),还有一些语法糖( user?.address)。 大部分人想要的不就是糖吗?谁会关心和类型和积类型的区别,自己写得爽就行了。 即使 Optional 这类方案,没有糖也很难受,比 if err != nil 好看不到哪儿去。 比如 Rust 没有任何糖的上抛: let ret = match foo() { Ok(v) => v, err => return err, } 后面大家受不了,加入了 try! 宏: let ret = try!(foo()); 再后面直接加入了问号运算符: let ret = foo()?; |
12 lesismal 214 天前 讲究工程性的工程师多数会觉得 if err 很好。 我自己就是这种支持 if err 的,从没因为在 go 里写多几个 if err 感到任何不适,反而觉得这种强制或习惯让代码更健壮了、甚是欣慰。 引用一段别人文章里总结的 Rob Pike 老爷子内容: 显式错误处理:if err != nil 的模式强制开发者在调用点处理错误,使得问题更难被“隐藏”到上层去统一“包装”处理,鼓励在错误发生的源头附解决或添加上下文。 完整文章: https://tonybai.com/2025/04/27/rob-pike-on-bloat/ |
13 zzhirong OP @lesismal 我也认为显式比隐式更好, 目前吐槽最多的应该是, 显式上抛以及层层上抛(导致了很多重复的代码), 在翻看 #2 给出的链接中的提案时, 发现一句话, "The goal is not to replace all error handling. The goal is to replace the most common case", 我也很认可, 针对高频的用法做些优化, 也未尝不可。 |
14 log4j 214 天前 习惯了表示还行,显示处理 error 工程上来讲还是很好的 |
17 Hopetree 214 天前 我现在写 Python 还经常借鉴 Go 的这种显示的异常语法,Go 又不是强制让你这么写,你要是不想判断你就直接异常不就行了 |
18 henix 214 天前 我比较喜欢 Go 这种错误处理方式,它的问题在于代码嗦,而且没有宏,而且按照 Go 语言的设计哲学,基本上不可能加入宏的 我自己的 C 语言基础库的错误处理就参考了 Go ,而且通过宏来减少重复代码,例如: #define E(s) { err_t err = s; if (err != NULL) return err; } (void)0 使用: E(do_some_thing(a)); |
19 bruce0 214 天前 go 通过返回值判断错误的方式我觉得挺好的,现在写 CPP 很多我都这样写,用 pair 或者 tuple, cpp23 有了 expected, go 的问题就是要写太多的 if err != nil , 如果能使用 check, try, ? 关键字或者符号,简化一下代码,那真的非常爽了 |
20 chor02 214 天前 我也不明白为什么不能有默认如果 err 不为空直接返回 err 的方案 |
21 ltaoo1o 214 天前 第一次接触到这种错误处理方案还是在 rust ,操作返回「结果」而不是「数据」,然后我就在 js 项目中引入了,配合 ts ,代码更健壮了 ```js const r = await dosomething(); if (r.error) { return; } // <-- 如果没有上面 if r.errror ,直接获取 r.data 在编辑器里面就会给出提示,r.data 可能是空 console.log(r.data); ``` |
22 LawlietZ 214 天前 这个问题讨论了八九年了吧 ? |
23 server 214 天前 各有各的优势,各有各的问题,习惯就好了 |
24 huigeer 214 天前 习惯就好, |