Golang Go语言中想为Go添加一个错误处理语法糖 !err,大家来看看这种错误处理方式如何
简介
这是一个为 Go 添加 !err 错误处理语法糖的项目, 与 Go 完全兼容(毕竟只是语法糖)
有了它你可以写如下代码, 代码更加紧凑 阅读更轻松
转换前:
package main
import (
“fmt”
“os”
)
func main() {
body, !err := readSelf()
fmt.Println(“main.go content”)
fmt.Println(body)
}
func readSelf() (content string, err error) {
body, !err := os.ReadFile(“main.go”)
content = string(body)
return
}
转换后:
package main
import (
“fmt”
“os”
)
func main() {
body, err := readSelf()
if err != nil {
return
}
fmt.Println(“main.go content”)
fmt.Println(body)
}
func readSelf() (content string, err error) {
body, err := os.ReadFile(“main.go”)
if err != nil {
return
}
content = string(body)
return
}
项目地址: https://github.com/gone-lang/gone
先来问问各位大佬的意见, 看下怎么做比较好
Golang Go语言中想为Go添加一个错误处理语法糖 !err,大家来看看这种错误处理方式如何
更多关于Golang Go语言中想为Go添加一个错误处理语法糖 !err,大家来看看这种错误处理方式如何的实战教程也可以访问 https://www.itying.com/category-94-b0.html
照你的方法,如果在报错的想打印日志应该怎么做呢,比如:<br>if err != nil {<br> logger.Error("something wrong")<br> return err<br>}<br>
更多关于Golang Go语言中想为Go添加一个错误处理语法糖 !err,大家来看看这种错误处理方式如何的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
个人感觉其实 没必要每个错误都去处理,关键点判断好,单元测试写好,应该就可以了。
例如
var u entity.User
_=dao.User.Ctx(ctx).Scan(&u,“id”,uid)
if u.id==0{
return fmt.error(“user does not exist”)
}
// 这里直接返回自定义的错误,中间件也好其他处理,比如多语言返回
if err != nil {
return
}
好家伙 返回值都不要了?
看错了 有返回值
不过仍然感觉不是太好用,有些情况返回 err 但其他返回值可能也有用 意义可能不是很大
使用 defer 打印错误, 如果需要立即处理错误, 可以不是用语法糖使用原有的 if err != nil {}
模式. 语法糖是可以随时退出不使用的go<br>func readSelf2() (content string, err error) {<br> defer func() {<br> slog.Error("wrong", "err", err)<br> }()<br> body, !err := os.ReadFile("main.go")<br> content = string(body)<br> return<br>}<br><br>
并不会出现兼容性问题, 会另外生成一个转译后 go 文件, 与其他 go 库是无缝操作的, 你可以认为是 typescript 这种
其实你这里也是进行了一个错误处理的判断
if err != nil { 不带其他逻辑直接 return }
一个语法糖只为了对这么一个特定场景下少两三行代码,大概率不会给你过的
我很好奇附言里是怎么把 !err 打成 ierr 的…… 难道 lz 用的手写输入?
golang 该如何调用 go+ 代码库呢?
这个是一个已有的转译实现, 我用了 ierr
作为 !err
的替代, 但遇到了一些问题, 打断点需要到转译后的文件才能打上, 在开发中还蛮影响思路的, 后面想到了如果做成 golang 超集语言的话就可以打上断点, 于是又起了个仓库准备实现新思路
已有的转译实现: https://github.com/shynome/err4 , 现在正在用
(就像前段时间的帖子说的, 每个程序员都有改造语言的冲动, 我也是对 golang error 的错误处理不满意所以就有这么一个个尝试
真要做的话我觉得 rust 的方式就不错,语句末尾加一个问号。
按照 go 的 习惯 是不会加新的语法糖的 毕竟 go 写出来的代码 主要是为了 review 的人 看着舒服的
语言肯定朝着越来越好用的方向发展。
错误处理,目前看比较好用的有两种:
GOTO:Exception/Panic
正确错误二元组:Result<T, E>( Rust )
golang err 绝对不是正确的方向
有类型系统兜底呢,不是简单语法改改就能模仿
像 Rust 那样整个?作为语法糖?
err := handle()
if err != nil {
return fmt.Errorf(“Handle error: %w”, err)
}
===>
handle()?.Errorf(“Handle error”)
https://github.com/golang/go/issues/32437 这里有最全的 golang error handle 的意见
你这样不如
v, ? := xxx()
现在一堆 ai 辅助编程的插件 感觉收益不是那么明显。copilot 一个回车解决的事情。
func readSelf() (string, error) {
body, err := os.ReadFile(“main.go”)
if err != nil {
return “”,err
}
content = string(body)
return content,nil
}
这种怎么处理 🤔️
https://github.com/golang/go/issues?q=label%3Aerror-handling
看看这些数不清的提案,相信总有一个是比你这个想法优秀且被枪毙了的。
不如这样
body := readSelf()?
感觉无糖更方便,因为我已经告诉别人我是 Errlang 开发者了。
FP 才是最优解:
type Result[T any] struct { v T; err error }
func(r *Result[T]) IfErr(f func(error)) { if r.err != nil {f(err)} }
func fmap[A, B any](ra Result[A], f f(a) Result[B]) Result[B] {
if ra.err != nil { return f(ra.v) }
return Result[B]{err: error}
}
设计上用元组就是一个大的失误,值和错误不会同时出现。
而 rust 的枚举就是很好的设计,rust 的问号运算符也是一个好的语法糖。
偶尔会同时出现的,例如读写 socket 、文件可以失败的同时已经成功了一部分
不过我同意还是支持代数数据类型能解决不少问题
对于编程语言来说, 除非你有充分的理由, 否则不要加语法糖.
注: 我觉得这样写很 cool 就不是一个充分的理由.
想法挺好的… 但是没有明确的 return 语句却可能会 return ,有点孩怕, 感觉容易出事故
golang 称为 err-lang 也确实是实至名归,1/5 的代码行数是由 if err != nil {} 提供的
第一眼看成了 erlang 略过去了
拒绝的理由是我们已经拒绝过了这项提案,泛型也是被拒绝过的现在也加上去了。
正如 issue 里提到的回复:“golang 不会根据各种错误处理提案的喜爱程度对错误处理进行改进,golang 有自己的节奏”
panic 也会导致函数提前返回,相对于使用 panic 的错误处理方案 !err 不会有性能损失
最关键的问题是,一般是鼓励 wrap 一下错误,不然你只看到 io 错误,根本不知道是哪里的问题,排查起来头痛。
我也会拒绝你,你这等于给语言加了一个宏仅仅为了偷懒少写一些代码而已。
当然 go 的初期设计确实考虑的很简陋,更聪明一点的做法是像 zig 或 rust 那样。
go error 设计更大的问题是没有保存堆栈。对于仅仅多写一点代码的问题,完全可以用 ide 来自动补充来解决。
无论是你的设计还是 rust 的设计还是 zig 的设计,还是当前 go 的设计,都不影响阅读代码。 写代码只是为了偷懒,我认为没有完全的必要性添加此项更改。
在Go语言中添加一个新的错误处理语法糖 !err
是一个有趣的提议,但需要考虑其对语言简洁性、可读性以及兼容性的影响。
首先,Go语言以其简洁和明确著称,现有的错误处理方式(即 if err != nil
)虽然稍显冗长,但非常直观且易于理解。新的语法糖 !err
可能会让代码更简短,但也可能牺牲了一部分可读性,尤其是对于初学者来说。
其次,Go语言非常注重向后兼容,任何新的语言特性都需要确保不会破坏现有的代码库。引入 !err
这样的语法糖,需要仔细考虑其对现有代码和工具链(如编译器、格式化工具等)的影响。
最后,虽然 !err
看起来简洁,但在实际应用中可能并不总是那么直观。例如,当需要对错误进行进一步处理或记录时,if err != nil
的形式可能更加灵活和强大。
综上所述,虽然 !err
作为一个错误处理的语法糖在概念上很有吸引力,但在实际实施前需要全面评估其对语言本身、社区以及生态系统的影响。在Go语言的当前发展轨迹上,保持语言的简洁性、可读性和兼容性仍然是首要考虑的因素。因此,在现有的错误处理方式仍然有效且易于理解的情况下,引入新的语法糖可能需要更多的讨论和谨慎考虑。