golang 1.13 errors 包来了,不用写“err 气功波”代码 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
guonaihong
V2EX    程序员

golang 1.13 errors 包来了,不用写“err 气功波”代码

  •  
  •   guonaihong
    guonaihong 2019-10-14 09:34:13 +08:00 5973 次点击
    这是一个创建于 2197 天前的主题,其中的信息可能已经有所发展或是发生改变。

    这篇是对 errors 包 的姿势挖掘

    气功波错误代码

    从 http.Get()返回的错误 判断 syscall.ECONNREFUSED 错误.以前要对 go 标准库 error 结构有点熟悉,才能写出下面的代码

    func CmdErr(err error) { if err == nil { return } if uerr, ok := err.(*url.Error); ok { if noerr, ok := uerr.Err.(*net.OpError); ok { if scerr, ok := noerr.Err.(*os.SyscallError); ok { if scerr.Err == syscall.ECONNREFUSED { fmt.Printf("gurl: (7) couldn't connect to host\n") return } } } } fmt.Printf("%s\n", err) } 

    用 go1.13 errors 库重构气功波代码

    现在只要知道,syscall.ECONNREFUSED 就行。先用 Unwrap 不停的解包 error。最后可能得到需要的 err

    func newCmdErr(err error) { for { err = errors.Unwrap(err) if err == nil { break } if err == syscall.ECONNREFUSED { fmt.Printf("gurl: (7) couldn't connect to host\n") return } } } 

    交流学习

    一起挖掘 errors 包的用法

    github

    https://github.com/guonaihong/gout

    第 1 条附言    2019-10-14 12:25:14 +08:00

    // 这是代码量最少的写法。

    func newCmdErr2(err error) { if errors.Is(err, syscall.ECONNREFUSED) { fmt.Printf("gurl: (7) couldn't connect to host\n") return } } 
    20 条回复    2019-10-15 08:15:25 +08:00
    rootxigua
        1
    rootxigua  
       2019-10-14 10:11:16 +08:00
    那如果 err 不为空,并且不等于 syscall.ECONNREFUSED,这个循环会结束吗?
    edussx
        2
    edussx  
       2019-10-14 10:28:33 +08:00
    @rootxigua 这种情况下 errors.Unwrap(err)这行会一直跑,直到返回 nil,然后在下面 break 跳出循环

    具体参考这个方法的实现: https://golang.org/src/errors/wrap.go?s=372:400#L4
    lizhenda
        3
    lizhenda  
       2019-10-14 10:45:35 +08:00
    看起来写法不错,更易读了
    rootxigua
        4
    rootxigua  
       2019-10-14 11:35:04 +08:00
    @edussx 懂了。源码很清晰,谢谢
    reus
        5
    reus  
       2019-10-14 11:38:45 +08:00   3
    难道不是 errors.Is(err, syscall.ECONNREFUSED) 就行了?
    iugo
        6
    iugo  
       2019-10-14 11:43:19 +08:00
    还是觉得 Go 的错误处理是个值得商榷的点.
    Hanggi
        7
    Hanggi  
       2019-10-14 12:07:38 +08:00
    这个代码本来就不用写什么气功波吧?有谁会这么写吗?
    guonaihong
        8
    guonaihong  
    OP
       2019-10-14 12:23:42 +08:00
    @reus 是的,这是最优解。
    boyhailong
        9
    boyhailong  
       2019-10-14 12:26:48 +08:00
    气功波? 返回值不想处理可以忽略的
    guonaihong
        10
    guonaihong  
    OP
       2019-10-14 12:28:45 +08:00
    @boyhailong 这里的用法是,如果是 syscall.ECONNREFUSED 的错误打印 提示信息。所以就不能忽略。。。
    guonaihong
        11
    guonaihong  
    OP
       2019-10-14 12:38:30 +08:00
    @iugo 是的,现在比较大的痛点有

    ``` go
    fd, err := os.Open("文件")
    if err != nil {
    return err
    }
    ```
    如果 go 里面有语法糖,在语句结尾加个符号,生成 if err != nil { return err}的代码就好了。比如下面的伪代码.
    fd, err := os.Open("文件“) ?
    ChristopherWu
        12
    ChristopherWu  
       2019-10-14 17:12:52 +08:00
    实不相瞒,我看不懂这代码在搞啥子
    ```
    func CmdErr(err error {
    if err == nil {
    return
    }

    if uerr, ok := err.(*url.Error); ok {
    if noerr, ok := uerr.Err.(*net.OpError); ok {
    if scerr, ok := noerr.Err.(*os.SyscallError); ok {
    if scerr.Err == syscall.ECONNREFUSED {
    fmt.Printf("gurl: (7) couldn't connect to host\n")
    return
    }
    }
    }
    }

    fmt.Printf("%s\n", err)
    }
    ```
    guonaihong
        13
    guonaihong  
    OP
       2019-10-14 18:00:35 +08:00
    @ChristopherWu 查询 err 看是否包含 syscall.ECONNREFUSED 这种情况。go1.13 以前只能这么干。。
    Nitroethane
        14
    Nitroethane  
       2019-10-14 18:30:31 +08:00 via Android
    @guonaihong 这不就是 rust 中的语法么...
    guonaihong
        15
    guonaihong  
    OP
       2019-10-14 18:50:03 +08:00
    @Nitroethane 对的,伪代码符号参考的 rust ?号,go 现在没有,有就好了。
    EscYezi
        16
    EscYezi  
       2019-10-14 21:06:36 +08:00 via iPhone
    不停的 unwrap 怎么看起来像在手动完成 java 的 printStackTrace......
    guonaihong
        17
    guonaihong  
    OP
       2019-10-14 21:20:47 +08:00
    @EscYezi 没玩过 java。。。
    mason961125
        18
    mason961125  
       2019-10-14 21:25:01 +08:00
    这样写,我觉得 https://github.com/hashicorp/errwrap 更好
    guonaihong
        19
    guonaihong  
    OP
       2019-10-14 21:52:51 +08:00
    @mason961125 谢了,我明天玩下。
    zjh6
        20
    zjh6  
       2019-10-15 08:15:25 +08:00
    气功波,是搞笑.
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2657 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 03:16 PVG 11:16 LAX 20:16 JFK 23:16
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86