自己写的 go 代码就是由一堆的 if 搭起来的 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
bandian
V2EX    程序员

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

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

    代码里面在疯狂的 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     Solana     5161 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 03:49 PVG 11:49 LAX 20:49 JFK 23:49
    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