Golang Go语言中如何优雅的处理 err
Golang Go语言中如何优雅的处理 err
go 中大部分短赋值都会有一个 xx, err :=
难道要每次都 if err != nil 么
大佬都是用什么方式处理的?
func checkErr(err error) {
if err != nil{
panic(err)
}
}
这样貌似也很低级啊
不用 hack 第三库只能这样,或者等 go2.0
更多关于Golang Go语言中如何优雅的处理 err的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
很久以前研究 GO 的时候,仿佛还说这种 if err != nil 的方式是优点,参数类型放在后面也是优点 …… 我几乎相信了……
反正我是写 if err != nil return 写吐了
这个是真的不方便,try catch finally 被 Go 搞成 err != nil, recover, defer
多返回值的滥用。。
在 vscode 里打 ife 然后自动补全……
因为 golang 里概率最大的是返回一个 struct 的指针加 err,所以自动补全的这个也是返回 nil,err
如果只有一个返回值 err,再按 tab 把 nil 删掉就好了。
其实也就看起来浪费行数,用起来还是不错的,各种地方都无脑返回,只在最高层统一处理就好了。
API 的话可以在框架集中处理,参考我这篇文章
https://zhuanlan.zhihu.com/p/26300634
if err != nil 是真的太啰嗦,
这是所谓的“特性”,无解。
关键是这种写法<br>if err:= xxx; err != nil {<br> //<br>}<br>
刚开始写 go 的时候很不习惯,跟 for 神似……
err := xxx 空格打多了
我现在已经接受了这种写法了,反过来想,C 不是也得判断返回值是否大于 0 吗
趁早放弃 go 吧
Live Templates 缓解一下
错误处理本来就是个大难题, 异常也不见得有好多多少
但是在 go 里面逢错误就 panic 的写法毫无疑问很低级
和 rust 的 Result 有得一拼
这个让我想起了地铁的手指口呼.
https://zh.wikipedia.org/wiki/%E6%8C%87%E5%B7%AE%E7%A2%BA%E8%AA%8D
这样强迫 coder 显式处理每一个可能出现的错误,可以说是有好处的,可以说现在写输入 ife 已经成了肌肉记忆了 233333
看了下 Go 2 引入了 check & handle https://go.googlesource.com/proposal/+/master/design/go2draft-error-handling-overview.md#draft-design<br><br>func CopyFile(src, dst string) error {<br> handle err {<br> return fmt.Errorf("copy %s %s: %v", src, dst, err)<br> }<br><br> r := check os.Open(src)<br> defer r.Close()<br><br> w := check os.Create(dst)<br> handle err {<br> w.Close()<br> os.Remove(dst) // (only if a check fails)<br> }<br><br> check io.Copy(w, r)<br> check w.Close()<br> return nil<br>}<br><br>
异常可以不处理,一直抛啊。
习惯就好。
c 的返回也是这样写的。
一开始我写 java 的 try catch 也写吐了。
每个语言都有罗嗦烦人的地方。大部分情况只能你去适应了,不想适应就换语言吧。
虽然写的很不爽,但不能否认,这样写出来的程序是比脚本语言写出来的更健壮一些。另外 try … catch 也不见得有多好
这种比 try catch 要好,
写过 10 年 C++的 是这么认为的
完全同意,这 2 个点完全是 xxx 的存在,那个 err 我先不评价什么,毕竟是特性, 但是那个类型放后面
纯粹是为了跟别人不一样 而不一样。
用上 rust,只想说没有 nil 和 null 的世界真美好。回去看以前写的 go 代码,一堆 nil 堆的像屎山一样。。
老哥,rust 这么丑陋的语法和一堆符号是怎么克服的,我试了好多次想学,看着看着就想吐了。。
#26 不是我吐槽你,Rust 除了显式生命周期难看一点以外,其他都比 Go 好多了好吗? 而且现在有 Miri 和 NLL 的支持,很少机会能写到显式生命周期了(除非写底层)
跟异常一样,往上抛,调用方处理。
当然,如果是不能处理的错误,直接 panic 也没问题。
主要是各种符号太多了,看得我脑壳晕
用 golang,打 err 自动补全 if,还算可以接受
#29 可能我写习惯了,没发现有什么太多的符号(连 JS 的一半都没有呢)
|| 表示闭包
! 表示 宏
? 向上抛异常。
也就这几个比较特殊的
<br>client.get(uri).and_then(|res| { <br> println!("Response: {}", res.status()); <br><br> res.body().for_each(|chunk| { <br> io::stdout() <br> .write_all(&chunk) <br> .map_err(From::from) <br> }) <br> }); <br>
有种一口气走到底的感觉,有点喘不过气。像以前 js express 那种回调层层嵌套,全是匿名函数的错觉…
看看 gopheracdamey 写的系列文章 楼主问的问题 go github wiki 有很多好资料 仔细找找不难发现
把 book 看一遍,掌握 struct,enum,match,if let 这些东西先,觉得有意思了再继续深入
已经开始支持 async/await,后面不用 and_then 这种写法。romio 了解一下
我觉得 go 的错误处理写法没啥问题,但是通常我写 go 是基本不会写 panic 和 recover 的。。
Go 的错误处理除了啰嗦点,其实没什么大毛病,这点就是继承了 C 语言程序就是输入+输入出的设计,简单。try catch 这种也不是万能的。
错误处理 Go2 做了优化,应该会少写一些 if。
其实能和 Go 语言做比较的只有 C,拿其它语言和 Go 比都不是太恰当,比如指针这个概念,大多数现代语言都放弃了,但在 Go 中却是非常核心的东西。
还有面向对象的那一堆理论,Go 完全没有,怎么去和 Java 这种比较?
通过编辑器的 snippets 来自动完成有关错误处理的代码,工作效率会高很多
if err != nil {
log.Err("%s", err)
}
rob 想保持 go 简单和地道,现在关于 go 那些改进的方案,rob 说了,可能都不会合到 go2 里面。油管视频
我也有一个 FuckErr()
这些返回错误搞得栈信息全丢了
既然选择了 Go,那么就用 Go 的方式处理错误,Go 不是一门语法“优雅”的语言
问号操作符能缓解,等 async/await 稳定后写异步也能喘气了
但是 C 有 #define,可以弄成 CHECK_RETURN(function());
都说 if err != nil 不好,我想问,你们认为好的是怎样的?
我从 if err != nil 中学到了很多,原来这个底层调用也可能报错
就 Rust 而言,只有错误没有异常,可能出错的地方统一用 Result<Item,Error>代替,不想处理直接往上抛直接打?号,不想处理显示报错直接.unwrap (),不想处理直接忽略有 if let,不想处理带默认值有 unwrap_or(),想处理直接用 match 处理部分或全部情况,再或者结合 map 等函数式风格随意组合,多种方式随意选择,还有 IDE/编译器提示。
不过 go 选择了类 c 的风格,强调简单,那也没哪个好或者不好的了。
就 Result 这个设计就是吸收了多年 PL 研究成果的好东西,配合自带的各种方法,写起代码行云流水。错误能处理的就处理,不能处理就抛给 caller,还能配合编译器进行类型检查,Monad 的应用,这么好的东西有人理解不了,硬说跟 error code 一样,还能说什么。我觉得这些人用 Go 跟 C 都挺好的,记得不要忘记检查错误码就好了
defer
这都能讨论这么多,我的天,不就是个 Monad 随手就能解决的问题么,真是尴尬
你们这些都不看错误怎么处理的人 能写出什么严谨的程序
换个语言
pascal 也是放后面啊,还有 var
Rust 的 Result 和 Option 不知道比 go 的 err 高到哪里去了🙃。
习惯成自然
slice[0:100]
当 100 超出了 len(slice),就报错了,特别烦这个,有解决方案么
你为什么需要访问越界的元素?
吐槽 err 的几乎是喜欢把所有都错误 try catch 的人,虽然确实很啰嗦,但是这个特性写过 c/c++的人就知道,还是比较方便的.
更严谨,也更啰嗦,至少更能了解程序内部哪个地方出错了
挺好的 期待 2.0
java try catch 有堆栈信息啊,一样能看到哪行错了,把所有代码整个 try catch 完事。go 每一个调用都要写。
在Golang(Go语言)中,优雅地处理错误(err
)是编写健壮、可读和可维护代码的关键。以下是一些最佳实践:
-
立即检查错误:在函数调用后立即检查错误,避免错误被遗漏或延迟处理。例如:
file, err := os.Open("example.txt") if err != nil { log.Fatal(err) }
-
使用命名返回值:当函数有多个返回值时,特别是包含错误时,使用命名返回值可以提高代码清晰度。
func readFile(filename string) (string, error) { data, err := ioutil.ReadFile(filename) if err != nil { return "", err } return string(data), nil }
-
自定义错误类型:为特定错误定义类型,以便进行类型断言或类型开关,提供更详细的错误处理逻辑。
type MyError struct { Code int Message string } func (e *MyError) Error() string { return fmt.Sprintf("Error %d: %s", e.Code, e.Message) }
-
日志记录:在生产环境中,使用日志记录错误详细信息,而不仅仅是打印到标准输出或标准错误。
-
包装错误:使用
fmt.Errorf
或errors.Wrap
(需要github.com/pkg/errors
包)来包装错误,添加上下文信息。 -
避免panic:除非在无法恢复的严重错误情况下,否则避免使用
panic
。
通过遵循这些实践,你可以确保你的Go代码在处理错误时既优雅又高效。