The Go Programming Language
› http://golang.org/
› Go Playground
Go Projects
› Revel Web Framework
d0m2o08

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

  •  
  •   d0m2o08 · May 24, 2019 · 11234 views
    This topic created in 2730 days ago, the information mentioned may be changed or developed.
    go 中大部分短赋值都会有一个 xx, err :=
    难道要每次都 if err != nil 么
    大佬都是用什么方式处理的?

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

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

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

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

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

    这样强迫 coder 显式处理每一个可能出现的错误,可以说是有好处的,可以说现在写输入 ife 已经成了肌肉记忆了 233333
    chenset
    chenset
    May 24, 2019
    19
    看了下 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
    }

    ```
    cubecube
    cubecube
    May 24, 2019 via Android
    20
    异常可以不处理,一直抛啊。
    keysona
    keysona
    May 24, 2019❤️1
    21
    习惯就好。

    c 的返回也是这样写的。

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

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

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

    也就这几个比较特殊的
    pmispig
    pmispig
    May 24, 2019
    32
    @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 那种回调层层嵌套,全是匿名函数的错觉...
    beidounanxizi
    beidounanxizi
    May 24, 2019
    33
    看看 gopheracdamey 写的系列文章 楼主问的问题 go github wiki 有很多好资料 仔细找找不难发现
    impl
    impl
    May 24, 2019 via Android
    34
    @pmispig 把 book 看一遍,掌握 struct,enum,match,if let 这些东西先,觉得有意思了再继续深入
    impl
    impl
    May 24, 2019 via Android
    35
    @pmispig 已经开始支持 async/await,后面不用 and_then 这种写法。romio 了解一下
    ICKelin
    ICKelin
    May 24, 2019
    36
    我觉得 go 的错误处理写法没啥问题,但是通常我写 go 是基本不会写 panic 和 recover 的。。
    Hellert
    Hellert
    May 24, 2019
    37
    Go 的错误处理除了啰嗦点,其实没什么大毛病,这点就是继承了 C 语言程序就是输入+输入出的设计,简单。try catch 这种也不是万能的。
    错误处理 Go2 做了优化,应该会少写一些 if。

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

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