起因是看到 https://ex.noerr.eu.org/t/1128449?p=1#reply41 写了
"相比之下 if err != nil 95%的时候都很不优雅"
好像我也看到很多吐槽 Go 错误处理语法的, 以下错误处理策略摘录自<<The Go Programming Language>> :
有无更优雅的方式能够实现上面的处理策略?
已知的两种:
try except finally
除了实现 1 (上抛)优雅点, 剩下的也没看出多大优势,而且错误发生点和处理点不在同一处,这就注定需要额外的代码来重构上下文, 比如,打开 file1, 然后 file2, 但在打开第 file2 时发生错误,处理的时候得先判定是打开哪个文件出错了,再执行相应错误处理和回滚操作。 1
Ayanokouji 97 天前
我之前发的帖子,有不少评论的解决方案可以参考。
/t/1101542 |
![]() |
2
PTLin 97 天前 ![]() 你先把这一百多个被毙了的提案看一下吧,可以说 99%的人能想到的方法里面都有。
https://github.com/golang/go/issues?q=label:error-handling |
![]() |
4
pike0002 97 天前
|
![]() |
5
Subilan 97 天前 via iPhone
我觉得最难顶的还是频繁多次错误处理的场景,err 变量不能重定义,要么事先专门声明一个,要么专门为每一个错误单独起个名字来定义。有更好的办法吗?
|
![]() |
6
vczyh 97 天前
就用 err.nn 吧,别的越用越麻烦,实在不行就换语言吧
|
![]() |
7
vczyh 97 天前
|
![]() |
10
vczyh 97 天前
@Subilan 我一般这么写: https://imgur.com/a/x4qtu9A
|
11
aloxaf 97 天前 ![]() > 还有 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 97 天前
讲究工程性的工程师多数会觉得 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 97 天前
习惯了表示还行,显示处理 error 工程上来讲还是很好的
|
![]() |
17
Hopetree 97 天前
我现在写 Python 还经常借鉴 Go 的这种显示的异常语法,Go 又不是强制让你这么写,你要是不想判断你就直接异常不就行了
|
18
henix 97 天前
我比较喜欢 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 97 天前
go 通过返回值判断错误的方式我觉得挺好的,现在写 CPP 很多我都这样写,用 pair 或者 tuple, cpp23 有了 expected,
go 的问题就是要写太多的 if err != nil , 如果能使用 check, try, ? 关键字或者符号,简化一下代码,那真的非常爽了 |
20
chor02 97 天前
我也不明白为什么不能有默认如果 err 不为空直接返回 err 的方案
|
![]() |
21
ltaoo1o 97 天前
第一次接触到这种错误处理方案还是在 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 97 天前
这个问题讨论了八九年了吧 ?
|
![]() |
23
server 97 天前
各有各的优势,各有各的问题,习惯就好了
|
24
huigeer 96 天前
习惯就好,
|