V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
GoPHP
V2EX  ›  程序员

据说优秀的代码没有 else?

  •  1
     
  •   GoPHP · 2018-04-18 18:53:08 +08:00 · 16842 次点击
    这是一个创建于 2412 天前的主题,其中的信息可能已经有所发展或是发生改变。

    多个 if else 嵌套的代码估计大家都见过。。。头疼!

    但是其实很多 if else 可以简化成一个 if,不需要 else,举个例子:

    $books = getByAFunc()
    if($books) {
       do something ...
       return something
    }else {
       do something ....
       return something
    }
    

    看上去没什么毛病,但是根据业务需求,大部分是可以这么写:

    if($books) {
         do something...
         return something
    }
    do something...
    return something
    

    这只是举个例子,很多时候满足条件的只有一种情况,那我们就可以针对这一种情况处理,其他情况直接 return !

    还要一种写法是先处理可能出现的异常错误,然后最后执行下来的就是正确情况!

    147 条回复    2018-04-20 21:07:11 +08:00
    1  2  
    noNOno
        1
    noNOno  
       2018-04-18 19:11:19 +08:00   ❤️ 15
    个人比较认同:优秀的代码中 if 必定有 else
    "
    每个 if 语句都有两个分支的理由是:如果 if 的条件成立,你做某件事情;但是如果 if 的条件不成立,你应该知道要做什么另外的事情。不管你的 if 有没有 else,你终究是逃不掉,必须得思考这个问题的。
    "
    引用自:http://www.yinwang.org/blog-cn/2015/11/21/programming-philosophy
    whx20202
        2
    whx20202  
       2018-04-18 19:29:43 +08:00
    @noNOno #1 感谢分享这篇文章
    gouchaoer
        3
    gouchaoer  
       2018-04-18 19:30:29 +08:00
    python
    whx20202
        4
    whx20202  
       2018-04-18 19:36:15 +08:00
    @noNOno #1 话说你知道还有什么书,能讲讲代码解耦,可读性这些内容吗?我最近一直在思考这方面
    MinQ
        5
    MinQ  
       2018-04-18 19:37:27 +08:00 via Android
    @whx20202 设计模式方面的书
    linthieda
        6
    linthieda  
       2018-04-18 19:37:28 +08:00 via iPhone   ❤️ 2
    优秀的代码没有 if
    MinQ
        7
    MinQ  
       2018-04-18 19:37:51 +08:00 via Android
    @linthieda 是的我们一般用 switch (手动滑稽)
    noNOno
        8
    noNOno  
       2018-04-18 19:51:46 +08:00
    @whx20202 哈哈,没,我看这方面的书比较少.
    wellsc
        9
    wellsc  
       2018-04-18 19:54:22 +08:00
    据说优秀的代码没有 try exception,我到现在也没懂。
    noNOno
        10
    noNOno  
       2018-04-18 20:07:02 +08:00   ❤️ 3
    @linthieda
    @wellsc
    优秀的项目不需要代码,推荐给你们:
    https://github.com/kelseyhightower/nocode
    guog
        11
    guog  
       2018-04-18 20:07:57 +08:00 via Android
    @wellsc 优秀的代码怎么会有 exception(滑稽
    l30n
        12
    l30n  
       2018-04-18 20:08:40 +08:00
    优秀的代码只有一个 return。
    wizardforcel
        13
    wizardforcel  
       2018-04-18 20:10:06 +08:00 via Android
    @wellsc golang 了解一下
    zj299792458
        14
    zj299792458  
       2018-04-18 20:13:22 +08:00 via iPhone   ❤️ 1
    优秀的代码只有一个 return+1,曾经想在某个函数返回前加一段逻辑,却发现这个函数的中间花式 return,最后不得不找出每个 return 加一遍。
    wdlth
        15
    wdlth  
       2018-04-18 20:14:05 +08:00
    单出口党和多出口党的竞争
    wellsc
        16
    wellsc  
       2018-04-18 20:14:56 +08:00
    @guog #11 我也不懂啊,群里的 C++ 大佬说的,我一直没想明白
    wellsc
        17
    wellsc  
       2018-04-18 20:15:24 +08:00
    @wizardforcel #13 kotlin 也没有
    MinQ
        18
    MinQ  
       2018-04-18 20:23:55 +08:00 via Android
    @wellsc 因为妥善处理了所有可能出错的情况,不需要再另外捕获错误了
    liuminghao233
        19
    liuminghao233  
       2018-04-18 20:26:04 +08:00 via iPhone
    有这样想法的人肯定没用过 goto
    cs923
        20
    cs923  
       2018-04-18 20:29:43 +08:00 via Android
    好无聊的讨论
    k9982874
        21
    k9982874  
       2018-04-18 20:30:23 +08:00 via iPhone
    和我的观点一样,有没有 else 对机器来说一样,但是对代码阅读有很大好处。
    zxybird
        22
    zxybird  
       2018-04-18 20:34:06 +08:00   ❤️ 4
    及早把异常情况排除,剩下的,就是正常流程的代码。这样,就只要写逻辑,不用考虑其它。
    eg,没有登陆,直接检测,然后 return 掉,比 else 里面包下正常逻辑要好一点吧。
    看侧重点吧。如果业务逻辑就是很复杂,if else 能够确保逻辑准确性。对于那些,不能继续往下执行的分支,及早 return 掉吧。
    dobelee
        23
    dobelee  
       2018-04-18 20:47:31 +08:00 via Android
    我习惯倒置条件,把异常情况 return 出去,这样就不需要 else 了。没看出楼上说的有 if 必有 else 有啥好。
    Jeremial
        24
    Jeremial  
       2018-04-18 20:53:54 +08:00
    early return
    Jeremial
        25
    Jeremial  
       2018-04-18 20:55:30 +08:00   ❤️ 1
    ```public int SomeFunction(bool cond1, string name, int value, AuthInfo perms)
    {
    int retval = SUCCESS;
    if (someCondition)
    {
    if (name != null && name != "")
    {
    if (value != 0)
    {
    if (perms.allow(name)
    {
    // Do Something
    }
    else
    {
    reval = PERM_DENY;
    }
    }
    else
    {
    retval = BAD_VALUE;
    }
    }
    else
    {
    retval = BAD_NAME;
    }
    }
    else
    {
    retval = BAD_COND;
    }
    return retval;
    }```

    ```public int SomeFunction(bool cond1, string name, int value, AuthInfo perms)
    {
    if (!someCondition)
    return BAD_COND;

    if (name == null || name == "")
    return BAD_NAME;

    if (value == 0)
    return BAD_VALUE;

    if (!perms.allow(name))
    return PERM_DENY;

    // Do something
    return SUCCESS;
    }```
    GooMS
        26
    GooMS  
       2018-04-18 20:56:27 +08:00 via Android
    如果 if 太多就不写 else 了
    ostholz
        27
    ostholz  
       2018-04-18 21:03:56 +08:00
    很久很久以前, javaeye(iteye) 上有个贴子, 代码里如何不用 if. 他好像包装了 n 层, 最后还是逃不掉用 if.
    cxbig
        28
    cxbig  
       2018-04-18 21:09:13 +08:00
    不要 else 主要是因为一些人在一个 function 里集合了特别复杂的嵌套逻辑,导致代码可读性下降。
    所以推荐细化 function,尽量让它们做最简单的事情,把一些可复用的方法抽象出来,便于调用。
    crist
        29
    crist  
       2018-04-18 21:13:37 +08:00
    我一般能不用 else 就不用 else,不过这样没啥可吹的。
    MinQ
        30
    MinQ  
       2018-04-18 21:19:23 +08:00 via Android
    resharper 的规则里就是少用 else
    des
        31
    des  
       2018-04-18 22:00:07 +08:00 via Android   ❤️ 2
    不,优秀的代码没有代码
    https://github.com/kelseyhightower/nocode
    des
        32
    des  
       2018-04-18 22:07:11 +08:00 via Android
    @cxbig
    比如 if flag return true else return false 这样?
    lihongjie0209
        33
    lihongjie0209  
       2018-04-18 22:11:40 +08:00
    感觉是最初版本必须有 else, 不然在条件复杂的情况下你可能漏掉一些情况.

    也许在你加入单元测试之后, 然后可以把 else 重构掉, 这样最保险.
    muziki
        34
    muziki  
       2018-04-18 22:12:36 +08:00 via iPhone   ❤️ 5
    一些菜鸡实在没有干货显摆自己的实力就扯这种言论,以讹传讹
    brickyang
        35
    brickyang  
       2018-04-18 22:28:11 +08:00   ❤️ 1
    我就举一个例子。JavaScript 传统的回调函数通常长这样:(error, ...args) => {}

    最正统的做法就是在函数体内先写错误处理部分:

    {
    if(error) { // oops }

    // do something
    }

    如果有错误,先处理,这部分代码通常都很短(可能短至一行),接着写回调函数本身的逻辑,很清晰。

    如果坚持完整的 if-else 结构,那么所有的回调函数都长这个样子:

    {
    if(error) {
    // oops
    } else {
    // do something
    }
    }

    不知道你们怎么样,反正我是拒绝的。

    包括王垠和其他一些人宣称完整的(和嵌套的) if-else 更易于阅读,逻辑更清晰,但我自己的实践体验是:并非总是如此。

    很多时候嵌套的 if-else 更难以阅读,远不如不嵌套的逻辑结构清晰。所以我认为合理的做法是使用最易于阅读的方式,而不是死抠嵌套或不嵌套的 if-else。
    okzpy9425
        36
    okzpy9425  
       2018-04-18 22:31:05 +08:00
    死扣这个的才是搞笑呢。。。代码风格要结合你使用的语言,结合团队现有的代码规范,以及你自己写的是不是爽来决定。 代码只要读起来清晰易懂 用不用 else 又何妨呢?
    hahawangcc
        37
    hahawangcc  
       2018-04-18 22:34:55 +08:00 via Android
    3
    cxbig
        38
    cxbig  
       2018-04-18 22:49:16 +08:00
    @des
    你是说放一行?如果逻辑简单,长度不超标,可以。
    无 else 通常是:
    如果一个条件只有 2~3 行就可以 return,那就写进 if 里;然后 else 的部分不用再缩进了。看上去缩进不多。
    jukka
        39
    jukka  
       2018-04-18 22:53:47 +08:00 via iPhone   ❤️ 2
    优秀的代码甚至连 if 都没有,只有 pattern matching..
    zhangbohun
        40
    zhangbohun  
       2018-04-18 23:00:04 +08:00
    卫语句?
    phpcxy
        41
    phpcxy  
       2018-04-18 23:02:07 +08:00
    优秀的人写坨翔都优秀。
    willzhang
        42
    willzhang  
       2018-04-18 23:44:39 +08:00
    No Code is the best code.
    rosu
        43
    rosu  
       2018-04-18 23:51:34 +08:00 via Android
    怕的是选择结构多层嵌套。尽早 return
    GenkunAbe
        44
    GenkunAbe  
       2018-04-18 23:52:32 +08:00 via Android   ❤️ 1
    优秀的女生是没有性生活的。
    Kongtou
        45
    Kongtou  
       2018-04-18 23:54:20 +08:00 via Android
    优秀的程序员是不写前端的
    easylee
        46
    easylee  
       2018-04-19 00:01:44 +08:00
    优秀的代码连变量名都没有。(认真脸.jpg )
    Akarin
        47
    Akarin  
       2018-04-19 00:15:38 +08:00
    raawaa
        48
    raawaa  
       2018-04-19 00:35:24 +08:00 via Android
    你的想法特别的 JavaScript😂
    secondwtq
        49
    secondwtq  
       2018-04-19 00:35:37 +08:00
    @jukka Pattern Matching 点赞
    不过其实 if else expression 可以看做对 boolean 的 pattern matching 的语法糖,所以 expression based 也很重要
    tangzhangming
        50
    tangzhangming  
       2018-04-19 00:38:06 +08:00   ❤️ 1
    业务发展快,又挣钱的公司代码都特别烂 --- 鲁迅
    gabon
        51
    gabon  
       2018-04-19 00:42:55 +08:00 via Android
    if(condition){doshit()} if(! condition){dosomeshit()}这样可以吗
    crb912
        52
    crb912  
       2018-04-19 08:24:11 +08:00 via Android
    The else isn't needed,but it does help the casual reader understand the intent. —— 《 C++ Primer Plus 》第六版 p308.

    翻译:else 并不是必须的,但是它可以帮助粗心的程序员理解意图。

    就像,符号明明存在优先级,有时候明明不需要括号,却还要加括号。换句话说,代码是给别人看的,方便别人理解。
    gimp
        53
    gimp  
       2018-04-19 08:38:13 +08:00
    定义变量,if...else...进行差异化赋值,结尾统一 return
    huluhulu
        54
    huluhulu  
       2018-04-19 09:13:48 +08:00 via iPhone
    有 goto 就好了不需要 else
    projectzoo
        55
    projectzoo  
       2018-04-19 09:48:44 +08:00
    有些编码规范要求 if 一定要带 else。
    具体原因你可以看下:悬挂 else
    shihty5
        56
    shihty5  
       2018-04-19 09:48:47 +08:00
    考虑到大部分人写的代码都是业务代码,每个地方最好都有 else。
    e.g. 调用银行接口,000000 是成功,ERR 打头的是失败,其他不在返回码列表里的至少要打个日志或者抛个错误出来。不然到时候排查问题就死定了 0.0,系统高可用 4 个 9 瞬间变为 3 个 9
    th00000
        57
    th00000  
       2018-04-19 10:04:29 +08:00
    一般的代码为了性能都会要求快速失败, 优先判断失败的规则, 测试起来也更方便, 所有 else 很少能见到
    以上
    cloudzhou
        58
    cloudzhou  
       2018-04-19 10:15:58 +08:00
    @noNOno
    我当时看 yinwang 都惊讶了,因为几乎所有的编程实践,都是推荐尽力减少 else
    yinwang 是某一方面的专家,但不一定是一个精通写代码的人,你要知道这两方面的区别。不要盲目随从。

    你可以看一下 @zxybird 的解释
    prolic
        59
    prolic  
       2018-04-19 10:20:53 +08:00
    这话题如果换到知乎,就已经有好几篇仿优秀的女生没有性生活的段子出来了
    noNOno
        60
    noNOno  
       2018-04-19 10:27:18 +08:00
    @cloudzhou 看了.
    我觉得这里讲得 if/else 只是表象.
    本质上的好处是,在写代码时,将自己代码的潜在问题,自己解决掉,而不是将问题放到其他地方.

    if/else 就是最好的例子,写了 if 不写 else,那么看代码的人遇到 else 的情况就需要重新思考.

    每个人的代码习惯都是信仰,不要争论为好~~
    ^-^
    AckywOw
        61
    AckywOw  
       2018-04-19 10:38:41 +08:00
    优秀的代码,该有的 else 必须有,这么多的 return 才是不推荐的
    inkWave
        62
    inkWave  
       2018-04-19 10:39:39 +08:00
    @cloudzhou 请问是有哪些书本还是文章吗?我一直看到的,听到的,都是建议写上 else.没见过推荐尽力减少 else 的.
    di94sh
        63
    di94sh  
       2018-04-19 10:46:00 +08:00 via Android
    @zj299792458 装饰器。
    cnbobolee
        64
    cnbobolee  
       2018-04-19 10:50:53 +08:00
    哪有什么优秀不优秀,既然语言设计出了这玩意,就必有他存在的理由。
    Felldeadbird
        65
    Felldeadbird  
       2018-04-19 10:55:18 +08:00
    JS 这么干就是作死。
    ai277014717
        66
    ai277014717  
       2018-04-19 10:55:35 +08:00
    没有 else 可读性直线下降。
    else 可以有,不宜嵌套太多。
    xubeiyan
        67
    xubeiyan  
       2018-04-19 10:59:26 +08:00
    都 8021 年了还有人在吹垠神吗
    monkeylyf
        68
    monkeylyf  
       2018-04-19 11:03:57 +08:00
    if 是不能完全避免的,好的数据结构或算法可以让 if 的出现频率减少。
    if 如果是在函数头部简短的做 condition check,个人觉得可以不写 else。但是如果不简短,尽量加 else。
    如果有 elseif,那尽量加 else,即使 else block 里面什么都不做。
    cluulzz
        69
    cluulzz  
       2018-04-19 11:07:13 +08:00
    @des #31 这仓库...天才...
    stnaw
        70
    stnaw  
       2018-04-19 11:09:01 +08:00
    不对 你们说的都不对

    优秀的代码应该没有 BUG
    agagega
        71
    agagega  
       2018-04-19 11:12:04 +08:00
    垠神的逻辑很好理解啊。你想想函数式语言,真没有副作用了,全都是表达式,没有隐式 null,那有 if 就必有 else,逼着你理清代码,然后用 Maybe Monad 这样的东西整理逻辑,不然层层 if else 写起来就像回调地狱。

    而如果你不在乎副作用,而且本来就需要一堆 Guard Condition,像楼主的方法就很清晰。
    qianmeng
        72
    qianmeng  
       2018-04-19 11:14:41 +08:00 via iPhone
    if else 只是一个工具而已,在考虑效率和功能的基础上,才能研究这些东西,我觉得 else 是不可缺少的,因为总有挑战程序员的事情出现
    xiaowangge
        73
    xiaowangge  
       2018-04-19 11:38:21 +08:00
    游戏业务逻辑了解一下?

    各种 if else else else
    china521
        74
    china521  
       2018-04-19 11:48:09 +08:00
    if else 是什么东东,我写代码只有 cmp jnz xchg 这些。好高大上的样子. -:)
    GoPHP
        75
    GoPHP  
    OP
       2018-04-19 12:02:42 +08:00
    各位大佬说的都对
    guoli100
        76
    guoli100  
       2018-04-19 12:05:45 +08:00 via iPhone
    haskell 等函数式语言,if 也是表达式,所以必须要有 else。

    好处是你可以用 if 来赋值了。
    locktionc
        77
    locktionc  
       2018-04-19 12:08:34 +08:00
    给一个 Python 的写法,不用 if

    ```python

    def parse_right_answer():
    xxxx

    def parse_wrong_answer():
    yyy

    def parse_other():
    zzz

    swith = {'true': parse_right_answer, 'false': parse_wrong_answer}

    switch.get(answer, parse_other)()
    ```
    bumz
        78
    bumz  
       2018-04-19 12:08:55 +08:00
    有 if 没 else 通常意味着你没考虑周全。

    即便 else 中不需要代码(如不需要副作用),也应当写上以表明这种情况自己考虑了。

    允许有 if 没 else 容易写到一半忘记考虑另一半的可能性了,所以应当禁止。
    sike03
        79
    sike03  
       2018-04-19 12:32:38 +08:00 via Android
    我习惯在一个方法开始时,先去判断所有异常情况,有异常直接 return。最后再去写正确时的逻辑。
    jmu
        80
    jmu  
       2018-04-19 12:54:18 +08:00 via iPhone
    一锤定音:题主和一些答主肯定没看过《 cc 》,请没看过的赶快看相关章节。看过的就直接绕道吧,不要强答了,能说清楚还要那么厚的书干嘛
    HuangLibo
        81
    HuangLibo  
       2018-04-19 13:05:36 +08:00
    这世界上没有最好的语言(除了 PHP), 也没有最好的设计模式, 到底要不要写 if...else 以及是否需要多个 return, 都要根据具体情况来做选择.

    有的人啊, 总想搞个大新闻, 还是要提高自己的恣肆水平(手动长者脸)
    laqow
        82
    laqow  
       2018-04-19 13:25:28 +08:00 via Android
    不同语言特点不一样,PHP 做逻辑判断的手段很多,或运算和三目运算就已经解决大部分简单逻辑了,view 部分用这些代码还简洁些,python 写太复杂缩进看的眼晕,抛异常退栈和各种语法糖看着简单些,至于 c 一类的能怎么严谨写怎么严谨最好,不然出 bug 的时候能死人
    yiplee
        83
    yiplee  
       2018-04-19 13:26:21 +08:00
    aokihu
        84
    aokihu  
       2018-04-19 13:26:29 +08:00 via Android
    if 一定要跟 dlse 配套,否则会出现低级逻辑错误
    dychenyi
        85
    dychenyi  
       2018-04-19 13:36:17 +08:00
    看情况吧。 这种我倒是经常写。
    if (! pointer )
    return;
    pointer->doSomething();
    shyrock
        86
    shyrock  
       2018-04-19 13:41:27 +08:00
    优秀的代码?没有!
    honeycomb
        88
    honeycomb  
       2018-04-19 13:48:49 +08:00 via Android
    不用 else,而是用 guard 方式,很多时候是为了 if else 层级过多导致的错误。

    如果层级很简单,为什么不用?
    chenyu0532
        89
    chenyu0532  
       2018-04-19 13:50:34 +08:00
    据说优秀的程序员都不用手敲代码,用嘴敲
    picasso2501
        90
    picasso2501  
       2018-04-19 14:06:05 +08:00
    if 和 return 配,和 break 配。
    需要写 else 的人,函数体都很长,过得都很辛苦。
    supermao
        91
    supermao  
       2018-04-19 14:25:16 +08:00 via iPhone
    @noNOno 这个说法其实有点片面,如果 if 里直接有 return 的,不需要有 else,多此一举,否则还是需要 else
    Phariel
        92
    Phariel  
       2018-04-19 14:38:22 +08:00 via Android
    多入口 单出口 这是我 coding 的原则
    peinhu
        93
    peinhu  
       2018-04-19 14:44:30 +08:00
    个人认为,不是“优秀的代码没有 else ”,而是“优秀的代码没有 if else ”,都是用各种设计模式拆分成更细分的单独类了,不过那样需要很高的编码水平,以及会把代码复杂化,导致别人可能一时半会儿看不懂你的代码,而且写起来也慢,实现相同功能的代码量更多。
    Ixizi
        94
    Ixizi  
       2018-04-19 14:55:53 +08:00
    优秀的代码没有分号(
    iyangyuan
        95
    iyangyuan  
       2018-04-19 14:56:52 +08:00
    个人习惯吧,逻辑清晰就好,我就比较少用
    iwishing
        96
    iwishing  
       2018-04-19 15:50:24 +08:00
    说自己的代码用 if 从来不用 else 的,就好像是说自己的代码从来没有 bug 一样
    一个条件判断输入的变量,一般来讲有 4 种情况,true,false,null,'',后三者都会走 else,不走 else 就要在之前全部判定掉
    不管怎么说,加 else 是个好习惯
    jalena
        97
    jalena  
       2018-04-19 16:04:29 +08:00
    全用三目运算符算不算没有 if 或 else。???
    alexnevsky
        98
    alexnevsky  
       2018-04-19 16:35:47 +08:00
    怎么写要看什么情况,可读性和性能挑一个。优秀的人早升官不写了
    lfzyx
        99
    lfzyx  
       2018-04-19 16:38:19 +08:00
    请用逻辑来理解 if else 的逻辑意义,而不是从什么可读性,优雅性,来看待这个逻辑
    wweir
        100
    wweir  
       2018-04-19 16:43:10 +08:00 via Android
    来个 if else 互相嵌套十层,估计就没人会质疑 if 搭配 return 的玩法了。

    要知道,复杂逻辑的分支结构,来个十层嵌套并不算过份。当然,会需要这类代码的地方不多。
    一般我们会用抽取函数、方法之类的方式,让代码清晰一点
    1  2  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   902 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 20:09 · PVG 04:09 · LAX 12:09 · JFK 15:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.