想为 golang 添加一个错误处理语法糖 !err, 大家来看看这种错误处理方式如何

251 天前
 sofukwird

简介

这是一个为 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

先来问问各位大佬的意见, 看下怎么做比较好

3787 次点击
所在节点    Go 编程语言
36 条回复
AKAUP
251 天前
照你的方法,如果在报错的想打印日志应该怎么做呢,比如:
```
if err != nil {
logger.Error("something wrong")
return err
}
```
morri
251 天前
个人感觉其实 没必要每个错误都去处理,关键点判断好,单元测试写好,应该就可以了。

例如

var u entity.User
_=dao.User.Ctx(ctx).Scan(&u,"id",uid)

if u.id==0{
return fmt.error("user does not exist")
}

// 这里直接返回自定义的错误,中间件也好其他处理,比如多语言返回
rekulas
251 天前
if err != nil {
return
}
好家伙 返回值都不要了?
rekulas
251 天前
@rekulas 看错了 有返回值
不过仍然感觉不是太好用,有些情况返回 err 但其他返回值可能也有用 意义可能不是很大
rekulas
251 天前
有个大问题是带来了兼容性问题, 我喜欢 go 的就是一次编码到处运行,如果用这种可能就得变成一次编码到处配置环境..用户下载一份源码,发现还无法编译得单独配置下,妥妥有前些年好压的既视感了,除非官方支持
sofukwird
251 天前
@AKAUP 使用 defer 打印错误, 如果需要立即处理错误, 可以不是用语法糖使用原有的 `if err != nil {}` 模式. 语法糖是可以随时退出不使用的
```go
func readSelf2() (content string, err error) {
defer func() {
slog.Error("wrong", "err", err)
}()
body, !err := os.ReadFile("main.go")
content = string(body)
return
}

```

@rekulas 并不会出现兼容性问题, 会另外生成一个转译后 go 文件, 与其他 go 库是无缝操作的, 你可以认为是 typescript 这种
@morri 其实你这里也是进行了一个错误处理的判断
lisxour
251 天前
if err != nil { 不带其他逻辑直接 return }

一个语法糖只为了对这么一个特定场景下少两三行代码,大概率不会给你过的
proxychains
251 天前
@morri 头像好评
cin
251 天前
sofukwird
251 天前
@lisxour 正是如此, 已经是被拒绝了所以另起炉灶来实现自己的需求
SingeeKing
251 天前
我很好奇附言里是怎么把 !err 打成 ierr 的…… 难道 lz 用的手写输入?
sofukwird
251 天前
@cin golang 该如何调用 go+ 代码库呢?
sofukwird
251 天前
@SingeeKing 这个是一个已有的转译实现, 我用了 `ierr` 作为 `!err` 的替代, 但遇到了一些问题, 打断点需要到转译后的文件才能打上, 在开发中还蛮影响思路的, 后面想到了如果做成 golang 超集语言的话就可以打上断点, 于是又起了个仓库准备实现新思路

已有的转译实现: https://github.com/shynome/err4 , 现在正在用

(就像前段时间的帖子说的, 每个程序员都有改造语言的冲动, 我也是对 golang error 的错误处理不满意所以就有这么一个个尝试
lanlanye
251 天前
真要做的话我觉得 rust 的方式就不错,语句末尾加一个问号。
githmb
251 天前
Rust:
let Ok(bar) = foo() else {
return fuckyou
}
ganbuliao
251 天前
按照 go 的 习惯 是不会加新的语法糖的 毕竟 go 写出来的代码 主要是为了 review 的人 看着舒服的
vchroc
251 天前
语言肯定朝着越来越好用的方向发展。
错误处理,目前看比较好用的有两种:
GOTO:Exception/Panic
正确错误二元组:Result<T, E>( Rust )

golang err 绝对不是正确的方向
neoblackcap
251 天前
@lanlanye 有类型系统兜底呢,不是简单语法改改就能模仿
fioncat
251 天前
像 Rust 那样整个?作为语法糖?

err := handle()
if err != nil {
return fmt.Errorf("Handle error: %w", err)
}

===>

handle()?.Errorf("Handle error")
mcfog
251 天前
https://github.com/golang/go/issues/32437 这里有最全的 golang error handle 的意见

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

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

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

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

© 2021 V2EX