首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
beego
V2EX  ›  Go

请教一下怎么优雅的处理 go 中的 err

  •  
  •   d0m2o08 · 198 天前 · 4711 次点击
    这是一个创建于 198 天前的主题,其中的信息可能已经有所发展或是发生改变。
    go 中大部分短赋值都会有一个 xx, err :=
    难道要每次都 if err != nil 么
    大佬都是用什么方式处理的?

    func checkErr(err error) {
    if err != nil{
    panic(err)
    }
    }

    这样貌似也很低级啊
    61 回复  |  直到 2019-07-05 09:39:56 +08:00
        1
    guonaihong   198 天前
    不用 hack 第三库只能这样,或者等 go2.0
        2
    Fule   198 天前   ♥ 3
    很久以前研究 GO 的时候,仿佛还说这种 if err != nil 的方式是优点,参数类型放在后面也是优点 …… 我几乎相信了……
        3
    wangsongyan   198 天前
    反正我是写 if err != nil return 写吐了
        4
    lhx2008   198 天前
    这个是真的不方便,try catch finally 被 Go 搞成 err != nil, recover, defer
        5
    araraloren   198 天前
    多返回值的滥用。。
        6
    Muninn   198 天前
    在 vscode 里打 ife 然后自动补全……
    因为 golang 里概率最大的是返回一个 struct 的指针加 err,所以自动补全的这个也是返回 nil,err
    如果只有一个返回值 err,再按 tab 把 nil 删掉就好了。
    其实也就看起来浪费行数,用起来还是不错的,各种地方都无脑返回,只在最高层统一处理就好了。

    API 的话可以在框架集中处理,参考我这篇文章
    https://zhuanlan.zhihu.com/p/26300634
        7
    dodo2012   198 天前
    if err != nil 是真的太啰嗦,
        8
    Qzier   198 天前
    这是所谓的“特性”,无解。
        9
    HuasLeung   198 天前
    关键是这种写法
    ````
    if err:= xxx; err != nil {
    //
    }
    ````
    刚开始写 go 的时候很不习惯,跟 for 神似……
        10
    HuasLeung   198 天前
    @HuasLeung err := xxx 空格打多了
        11
    freestyle   198 天前 via iPhone
    https://imhanjm.com/2018/07/08/go 代码如何优雅地错误处理(error%20handling%20and%20go%201)/
        13
    pmispig   198 天前   ♥ 1
    我现在已经接受了这种写法了,反过来想,C 不是也得判断返回值是否大于 0 吗
        14
    zvall   198 天前
    趁早放弃 go 吧
        15
    chenset   198 天前
    Live Templates 缓解一下
        16
    zzn   198 天前
    错误处理本来就是个大难题, 异常也不见得有好多多少

    但是在 go 里面逢错误就 panic 的写法毫无疑问很低级
        17
    VDimos   198 天前 via Android
    和 rust 的 Result 有得一拼
        18
    Vegetable   198 天前
    这个让我想起了地铁的手指口呼.

    https://zh.wikipedia.org/wiki/%E6%8C%87%E5%B7%AE%E7%A2%BA%E8%AA%8D

    这样强迫 coder 显式处理每一个可能出现的错误,可以说是有好处的,可以说现在写输入 ife 已经成了肌肉记忆了 233333
        19
    chenset   198 天前
    看了下 Go 2 引入了 check & handle https://go.googlesource.com/proposal/+/master/design/go2draft-error-handling-overview.md#draft-design

    ```

    func CopyFile(src, dst string) error {
    handle err {
    return fmt.Errorf("copy %s %s: %v", src, dst, err)
    }

    r := check os.Open(src)
    defer r.Close()

    w := check os.Create(dst)
    handle err {
    w.Close()
    os.Remove(dst) // (only if a check fails)
    }

    check io.Copy(w, r)
    check w.Close()
    return nil
    }

    ```
        20
    cubecube   198 天前 via Android
    异常可以不处理,一直抛啊。
        21
    keysona   198 天前   ♥ 1
    习惯就好。

    c 的返回也是这样写的。

    一开始我写 java 的 try catch 也写吐了。

    每个语言都有罗嗦烦人的地方。大部分情况只能你去适应了,不想适应就换语言吧。
        22
    keepeye   198 天前
    虽然写的很不爽,但不能否认,这样写出来的程序是比脚本语言写出来的更健壮一些。另外 try ... catch 也不见得有多好
        23
    dabaibai   198 天前
    这种比 try catch 要好,
    写过 10 年 C++的 是这么认为的
        24
    SurfaceView   198 天前
    @Fule 完全同意,这 2 个点完全是 xxx 的存在,那个 err 我先不评价什么,毕竟是特性, 但是那个类型放后面
    纯粹是为了跟别人不一样 而不一样。
        25
    impl   198 天前 via Android
    用上 rust,只想说没有 nil 和 null 的世界真美好。回去看以前写的 go 代码,一堆 nil 堆的像屎山一样。。
        26
    pmispig   198 天前
    @impl 老哥,rust 这么丑陋的语法和一堆符号是怎么克服的,我试了好多次想学,看着看着就想吐了。。
        27
    Kilerd   198 天前
    @pmispig #26 不是我吐槽你,Rust 除了显式生命周期难看一点以外,其他都比 Go 好多了好吗? 而且现在有 Miri 和 NLL 的支持,很少机会能写到显式生命周期了(除非写底层)
        28
    ZSeptember   198 天前
    跟异常一样,往上抛,调用方处理。
    当然,如果是不能处理的错误,直接 panic 也没问题。
        29
    pmispig   198 天前
    @Kilerd 主要是各种符号太多了,看得我脑壳晕
        30
    gamexg   198 天前
    用 golang,打 err 自动补全 if,还算可以接受
        31
    Kilerd   198 天前
    @pmispig #29 可能我写习惯了,没发现有什么太多的符号(连 JS 的一半都没有呢)

    || 表示闭包
    ! 表示 宏
    ? 向上抛异常。

    也就这几个比较特殊的
        32
    pmispig   198 天前
    @Kilerd
    ```
    client.get(uri).and_then(|res| {
    println!("Response: {}", res.status());

    res.body().for_each(|chunk| {
    io::stdout()
    .write_all(&chunk)
    .map_err(From::from)
    })
    });
    ```
    有种一口气走到底的感觉,有点喘不过气。像以前 js express 那种回调层层嵌套,全是匿名函数的错觉...
        33
    beidounanxizi   198 天前
    看看 gopheracdamey 写的系列文章 楼主问的问题 go github wiki 有很多好资料 仔细找找不难发现
        34
    impl   198 天前 via Android
    @pmispig 把 book 看一遍,掌握 struct,enum,match,if let 这些东西先,觉得有意思了再继续深入
        35
    impl   198 天前 via Android
    @pmispig 已经开始支持 async/await,后面不用 and_then 这种写法。romio 了解一下
        36
    ICKelin   198 天前
    我觉得 go 的错误处理写法没啥问题,但是通常我写 go 是基本不会写 panic 和 recover 的。。
        37
    Hellert   198 天前
    Go 的错误处理除了啰嗦点,其实没什么大毛病,这点就是继承了 C 语言程序就是输入+输入出的设计,简单。try catch 这种也不是万能的。
    错误处理 Go2 做了优化,应该会少写一些 if。

    其实能和 Go 语言做比较的只有 C,拿其它语言和 Go 比都不是太恰当,比如指针这个概念,大多数现代语言都放弃了,但在 Go 中却是非常核心的东西。
    还有面向对象的那一堆理论,Go 完全没有,怎么去和 Java 这种比较?
        38
    knowckx   198 天前
    通过编辑器的 snippets 来自动完成有关错误处理的代码,工作效率会高很多

    if err != nil {
    log.Err("%s", err)
    }
        39
    impl   198 天前 via Android
    rob 想保持 go 简单和地道,现在关于 go 那些改进的方案,rob 说了,可能都不会合到 go2 里面。油管视频
    其实 go 这门语言多年前就死了。go2 可能就是画出来的大饼,什么时候能出来,没人知道。
        40
    loading   198 天前 via Android
    我也有一个 FuckErr()
        41
    zeromake   198 天前 via Android
    这些返回错误搞得栈信息全丢了
        42
    liuxey   198 天前
    既然选择了 Go,那么就用 Go 的方式处理错误,Go 不是一门语法“优雅”的语言
        43
    Nugine0   198 天前 via Android
    @pmispig 问号操作符能缓解,等 async/await 稳定后写异步也能喘气了
        44
    ysc3839   198 天前 via Android
    @pmispig 但是 C 有 #define,可以弄成 CHECK_RETURN(function());
        45
    index90   198 天前
    都说 if err != nil 不好,我想问,你们认为好的是怎样的?
        46
    RubyJack   198 天前
    我从 if err != nil 中学到了很多,原来这个底层调用也可能报错
        47
    WilliamYang   198 天前
    我已经习惯,并可能喜欢上它了
        48
    Skye347   198 天前 via Android   ♥ 2
    就 Rust 而言,只有错误没有异常,可能出错的地方统一用 Result<Item,Error>代替,不想处理直接往上抛直接打?号,不想处理显示报错直接.unwrap (),不想处理直接忽略有 if let,不想处理带默认值有 unwrap_or(),想处理直接用 match 处理部分或全部情况,再或者结合 map 等函数式风格随意组合,多种方式随意选择,还有 IDE/编译器提示。
    不过 go 选择了类 c 的风格,强调简单,那也没哪个好或者不好的了。
        49
    neoblackcap   198 天前   ♥ 4
    @Skye347 就 Result 这个设计就是吸收了多年 PL 研究成果的好东西,配合自带的各种方法,写起代码行云流水。错误能处理的就处理,不能处理就抛给 caller,还能配合编译器进行类型检查,Monad 的应用,这么好的东西有人理解不了,硬说跟 error code 一样,还能说什么。我觉得这些人用 Go 跟 C 都挺好的,记得不要忘记检查错误码就好了
        50
    skadi   198 天前 via iPhone
    defer
        51
    sunny352787   198 天前
    你们这帮 Java 转 Go 的肯定都喜欢 try,就是习惯
    你看像我们 C++转 Go 的从来不会提这类问题~
        52
    svenFeng   198 天前 via Android
    这都能讨论这么多,我的天,不就是个 Monad 随手就能解决的问题么,真是尴尬
        53
    petelin   198 天前 via iPhone
    你们这些都不看错误怎么处理的人 能写出什么严谨的程序
        54
    zhuangzhuang1988   198 天前
    换个语言
        55
    derek80   198 天前 via iPhone
    @SurfaceView pascal 也是放后面啊,还有 var
        56
    Tyanboot   198 天前 via Android
    @VDimos Rust 的 Result 和 Option 不知道比 go 的 err 高到哪里去了🙃。
        57
    python   197 天前 via Android
    习惯成自然
        58
    skiy   197 天前
    slice[0:100]
    当 100 超出了 len(slice),就报错了,特别烦这个,有解决方案么
        59
    neoblackcap   197 天前
    @skiy 你为什么需要访问越界的元素?
        60
    Karblue   197 天前
    吐槽 err 的几乎是喜欢把所有都错误 try catch 的人,虽然确实很啰嗦,但是这个特性写过 c/c++的人就知道,还是比较方便的.
    更严谨,也更啰嗦,至少更能了解程序内部哪个地方出错了
        61
    guanhui07   156 天前
    挺好的 期待 2.0
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   823 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 27ms · UTC 22:14 · PVG 06:14 · LAX 14:14 · JFK 17:14
    ♥ Do have faith in what you're doing.