V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Sponsored by
LinkedIn
不坐班的神仙工作 · 去任何你想去的地方远程,赚一线城市的工资
2000 个不用出门 Social 的全球远程工作,帮助 V2EX 的小伙伴开启全新的工作方式。
Promoted by LinkedIn
bandian
V2EX  ›  程序员

自己写的 go 代码就是由一堆的 if 搭起来的

  •  
  •   bandian · 2020-11-03 17:21:45 +08:00 · 6862 次点击
    这是一个创建于 691 天前的主题,其中的信息可能已经有所发展或是发生改变。

    代码里面在疯狂的 if 判断,其中 if err !=nil 最多,感觉一个函数三分之二都在写判断逻辑,这就是入门开发者吗

    38 条回复    2020-11-06 09:31:35 +08:00
    togou
        1
    togou  
       2020-11-03 17:40:36 +08:00   ❤️ 1
    主要有的东西感觉根本不会 err 的你就把他 _ 掉算了
    THESDZ
        2
    THESDZ  
       2020-11-03 17:42:26 +08:00
    是不是过度封装了?
    导致需要判断返回的地方太多了?
    lepig
        3
    lepig  
       2020-11-03 17:46:59 +08:00
    贴段代码看看
    sunorg
        4
    sunorg  
       2020-11-03 17:56:23 +08:00 via Android
    业务逻辑不就是这样??
    SuperMild
        5
    SuperMild  
       2020-11-03 18:05:58 +08:00
    if err !=nil 太多是 Go 的缺点,你可以看看剔除这个之后,if 还多不多。
    SuperMild
        6
    SuperMild  
       2020-11-03 18:06:39 +08:00
    更正:不是缺点,是特点。
    chenqh
        7
    chenqh  
       2020-11-03 18:07:16 +08:00
    有个问题,golang 加个默认值有那么困难吗?
    wysnylc
        8
    wysnylc  
       2020-11-03 18:23:29 +08:00
    @SuperMild #6 是特色,是进步!
    lewis89
        9
    lewis89  
       2020-11-03 18:25:53 +08:00
    如何看待百度无人车有 3 万个 if
    DeWhite
        10
    DeWhite  
       2020-11-03 18:25:56 +08:00
    if err 我个人觉得是一个好东西,我可以通过返回值 找到写报错的地方。
    jin7
        11
    jin7  
       2020-11-03 18:39:29 +08:00
    换语言 逃....
    jinliming2
        12
    jinliming2  
       2020-11-03 21:48:28 +08:00   ❤️ 3
    我觉得:Go 里的 if err != nil 判断是否出错,表明这里确实有可能出错,那么不论是什么编程语言,都是有可能出错的。
    比如写个除法函数,返回商和余数,但如果除数参数提供了 0,那么结果就是应该出错(不考虑返回无穷之类的情况)。
    在其他语言里,这叫“异常”,他们几乎都有 try-catch 语法,来捕获错误,比如:
    ```
    try {
    可能出错的函数 A();
    可能出错的函数 B();
    可能出错的函数 C();
    } catch (错误 A) {
    } catch (错误 B) {
    } catch (错误 C) {
    } finally {
    }
    ```
    在 Go 里面,实际上也有类似的写法:
    ```
    defer func () {
    if err := recover(); err != nil {
    // 判读 err 的类型,处理不同错误
    }
    // finally
    }()
    可能出错的函数 A()
    可能出错的函数 B()
    可能出错的函数 C()
    ```
    这样写是不是就有点类似了?
    但是不管是 try-catch 还是 panic-recover,他们的问题都是:抛出错误,在某个位置集中捕获。这样在代码层面你就不知道错误具体是在哪里抛出来的了,只能在运行时打堆栈,相同类型的错误也就只能是统一的处理方法。

    而 Go 语言的一般风格是:错误在哪里抛出,就在哪里处理掉,这样对错误的处理会比较明确。

    比如在一个函数里有两个除法运算,除数都有可能为 0 。那么 try-catch 就只能在捕获到错误时打一个除数为 0 的日志,而 Go 的风格则可以报第一步除数为 0 或是第二步除数为 0 。

    当然,try-catch 也可以写成 一行语句一个捕获的形式,那样的话比 if err != nil 更恐怖,而且还有变量块级作用域的问题。
    Mohanson
        13
    Mohanson  
       2020-11-03 21:58:43 +08:00   ❤️ 2
    只要胆子大, 贞子放产假

    https://github.com/mohanson/doa

    刚写的库, 就等 go1.17 上泛型可以带返回值类型了...
    Mohanson
        14
    Mohanson  
       2020-11-03 22:01:47 +08:00
    不过事实上我已经用 go2go 分支编译过, 换成泛型写法爽歪歪~

    现在自己写的几个库都在等泛型重写, 没泛型可真的要命
    leavic
        15
    leavic  
       2020-11-03 22:03:36 +08:00
    if err 我觉得根本是 golang 自己的坑
    Mac
        16
    Mac  
       2020-11-03 22:10:17 +08:00 via Android
    不是还有人用一堆 if 做游戏的嘛
    loolac
        17
    loolac  
       2020-11-03 23:17:28 +08:00
    @jinliming2 追溯错误来源一般都堆栈轨迹的吧,try-catch 可以根据错误处理继续后面的逻辑,比如错误可以导致返回结果的变更,但是 panic-recover 就很难做到了,golang 函数调用基本上都是传值,defer 函数中要改变返回内容,必须使用指针,而且封装逻辑也必须使用闭包函数,出错前后的代码逻辑和可复用部分的代码必须使用闭包函数封装,写出来的代码很“反”。
    hallDrawnel
        18
    hallDrawnel  
       2020-11-03 23:27:36 +08:00
    如果函数会出错,本来就应该处理错误呀。我觉得 if err != nil 虽然繁琐,但是从语法上强迫人处理错误是一件好事情。
    phithon
        19
    phithon  
       2020-11-03 23:59:47 +08:00
    学几个设计模式,多用些接口,可能会好点
    xyxy
        20
    xyxy  
       2020-11-04 00:38:40 +08:00
    诶 是因为新手,我新写 golang 也是这样的
    woahishui
        21
    woahishui  
       2020-11-04 07:37:43 +08:00 via Android
    @jinliming2 这个缺点没有必要这么解释,程序的异常判断是正常的,但是在哪一层用户进行捕获,进行处理是用户自己的事情,所以这种写法就是因为用户不知道怎么去抛出异常,怎么在统一位置处理异常,才有的疑问
    woahishui
        22
    woahishui  
       2020-11-04 07:39:33 +08:00 via Android
    或许楼主是对如何抛出异常,如何优雅的统一处理异常不知道在 golang 怎么处理才有的这种感觉
    ArJun
        23
    ArJun  
       2020-11-04 08:41:40 +08:00
    其实看情况的,有些 err 可以直接_替换,没必要写那么多判断 err
    ylsc633
        24
    ylsc633  
       2020-11-04 09:45:25 +08:00
    我情愿多写点 if err != nil

    对于排错真的很友好..

    对于一些十分有把握不会出现的 我直接 _
    chengxiao
        25
    chengxiao  
       2020-11-04 09:50:09 +08:00
    别想太多 写就是了
    到后面你会发现 如果没 error 返回
    更让人害怕
    a719031256
        26
    a719031256  
       2020-11-04 10:03:01 +08:00
    这种写法其实挺好的,出了问题也容易找,最怕拼了命的封装写法,那个找问题就像从一堆垃圾中找一颗针
    LANB0
        27
    LANB0  
       2020-11-04 11:11:00 +08:00
    @togou 感觉不会 err 的地方,到后面一定会遇到 err 。写代码不要想当然,不然猿类早消灭 bug 了
    stirlingx
        28
    stirlingx  
       2020-11-04 11:36:53 +08:00
    程序员的工作量不在于多写几个 if,而是排查 bug 。go 这种方式对找 bug 真的方便,可以省很多时间
    BoarBoar
        29
    BoarBoar  
       2020-11-04 11:48:18 +08:00
    等你写多了 你就会发现 if err !=nil 还是那么多
    nguoidiqua
        30
    nguoidiqua  
       2020-11-04 11:54:35 +08:00
    不用 if 就会别的,除非不写程序,我反正 try catch if 什么的都可以接受。
    kuro1
        31
    kuro1  
       2020-11-04 11:58:22 +08:00
    鲁棒性极佳
    dream4ever
        32
    dream4ever  
       2020-11-04 12:16:53 +08:00
    @Mohanson 就冲你这么大胆,我也要毫不留情地给你点个赞
    wzw
        33
    wzw  
       2020-11-04 13:23:24 +08:00 via iPhone
    @Mohanson 还要很久吧
    newtype0092
        34
    newtype0092  
       2020-11-04 13:52:19 +08:00
    @jinlimling2 看了你的对比,假如造一辆汽车,一般团队在关键结构用高强度材料进行加固,go 是把所有地方都用高强度制造,不计成本的生产方式?
    raaaaaar
        35
    raaaaaar  
       2020-11-04 13:58:27 +08:00 via Android
    提前 return,这样不会太臃肿,给 error 分层,多封装点接口。。。。然后你会发现还是那么多 if 。。
    sssooonnnggg
        36
    sssooonnnggg  
       2020-11-04 14:02:45 +08:00
    相比之下 rust 的 result+?就香疯了
    taowen
        37
    taowen  
       2020-11-04 14:07:41 +08:00
    qloog
        38
    qloog  
       2020-11-06 09:31:35 +08:00
    面向错误编程,今早处理错误,是很不错的一种方法。
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1752 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 51ms · UTC 00:08 · PVG 08:08 · LAX 17:08 · JFK 20:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.