这种一句话的 if, else 有没有优雅的处理方法? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
blue7wings
V2EX    PHP

这种一句话的 if, else 有没有优雅的处理方法?

  •  
  •   blue7wings 2015-03-20 09:57:11 +08:00 10960 次点击
    这是一个创建于 3916 天前的主题,其中的信息可能已经有所发展或是发生改变。
    if ($is_false)
    $this->rollback();
    else
    $this->commit();

    有没有像三元运算符那样,一条语句就搞定的?
    第 1 条附言    2015-03-20 17:57:58 +08:00 div class="sep5">
    还是采用了if,else的方式,即使一条语句也还是要加上{},可读性同样也是特别重要的,谢谢各位。。
    第 2 条附言    2015-03-24 15:00:45 +08:00
    《编写可读代码的艺术》,第一章的第二个例子就是说这个问题的,果然是学的不够多,滚去看书了。
    73 条回复    2015-03-23 12:59:41 +08:00
    mengzhuo
        1
    mengzhuo  
       2015-03-20 09:58:22 +08:00   2
    Readability counts.
    b821025551b
        2
    b821025551b  
       2015-03-20 10:01:15 +08:00
    直接三元就行了
    lizheming
        3
    lizheming  
       2015-03-20 10:02:00 +08:00
    额,这个不可以写成三元么?
    xjliao
        4
    xjliao  
       2015-03-20 10:02:02 +08:00
    同意3楼
    griffinqiu
        5
    griffinqiu  
       2015-03-20 10:04:35 +08:00   6
    $is_false && $this->rollback() || $this->commit();

    PHP是世界上最好的语言没有之一。
    killerand1983
        6
    killerand1983  
       2015-03-20 10:07:26 +08:00
    echo $is_false ? $this->rollback() : $this->commit()
    ALeo
        7
    ALeo &nbs;
       2015-03-20 10:11:01 +08:00   2
    用if else 就好了,好像效率还更高一点..

    顺便说一句,我真的看不惯别人写这种语句不加花括号...
    mcfog
        8
    mcfog  
       2015-03-20 10:12:44 +08:00 via Android   3
    这种情况就应该写多行没事把几句话硬挤在一起写就好像说话不停顿写字不加标点不仅不优雅简直就是在讨打
    killerand1983
        9
    killerand1983  
       2015-03-20 10:14:05 +08:00
    @griffinqiu 这个是什么语法呢?求解
    b821025551b
        10
    b821025551b  
       2015-03-20 10:14:16 +08:00
    @griffinqiu 你这是什么???
    zhicheng
        11
    zhicheng  
       2015-03-20 10:16:24 +08:00 via Android
    难道,大家都没有听说过函数这个东西吗?
    lyragosa
        12
    lyragosa  
       2015-03-20 10:17:19 +08:00
    @griffinqiu 窝巢,这个神了……
    br00k
        13
    br00k  
       2015-03-20 10:17:45 +08:00
    @griffinqiu 这样是错的。第一个为false,后面2个都不会执行。用三元没问题。
    haiyang416
        14
    haiyang416  
       2015-03-20 10:19:25 +08:00
    @killerand1983 不要用 @griffinqiu 的写法。
    Arrowing
        15
    Arrowing  
       2015-03-20 10:19:48 +08:00
    @griffinqiu 你这个是错的,如果$is_false为true的话,2个方法都会执行到。
    kmvan
        16
    kmvan  
       2015-03-20 10:20:55 +08:00
    wp源码,经常有

    if(true)
    return;
    br00k
        17
    br00k  
       2015-03-20 10:21:45 +08:00
    @Arrowing 为true的话,如果$this->rollback()返回false才会继续执行。返回true就不会执行||后面的了
    ETiV
        18
    ETiV  
       2015-03-20 10:27:55 +08:00 via iPhone
    三元:

    TrueOrFalse ? ExecTrue : ExecFalse

    某楼那个是(几乎?)所有高级点儿的编程语言的特性
    && 左边是 false 的时候直接返回 false,不执行右边的
    || 相反,左边是 true 的时候直接返回 true,不执行右边的
    killerand1983
        19
    killerand1983  
       2015-03-20 10:29:46 +08:00
    @griffinqiu 研究了十分钟终于懂了
    (a && b ) || c
    killerand1983
        20
    killerand1983  
       2015-03-20 10:30:17 +08:00
    @griffinqiu 研究了十分钟终于懂了
    ((a) && (b) ) || c
    XCaiEr
        21
    XCaiEr  
       2015-03-20 10:31:20 +08:00 via iPhone
    Bool ? A : B;
    finian
        22
    finian  
       2015-03-20 10:31:49 +08:00
    killerand1983
        23
    killerand1983  
       2015-03-20 10:34:07 +08:00
    搭车:
    为什么 $is_false ? echo 111 : echo 222; 不行
    $is_false ? print 111 : print 222; 就可以
    sudoz
        24
    sudoz  
       2015-03-20 10:36:31 +08:00
    ? : 三目运算 一行搞定啊
    ALeo
        25
    ALeo  
       2015-03-20 10:43:21 +08:00   1
    @killerand1983 echo不能使用在表达式里面..它算不上是一个函数
    SuujonH
        26
    SuujonH  
       2015-03-20 10:48:47 +08:00
    @Arrowing 似乎不会吧,记得&& 是符合了第一个条件才会判定后面的
    ericls
        27
    ericls  
       2015-03-20 10:49:37 +08:00
    我觉得楼主的就挺优雅的 比楼下的一行的好
    b821025551b
        28
    b821025551b  
       2015-03-20 10:50:13 +08:00   1
    @killerand1983 用 echo $is_false ? 111 : 222;echo只是个语言结构,而print是个有返回值的函数
    aWangami
        29
    aWangami  
       2015-03-20 10:51:06 +08:00
    问号表达式
    goodbest
        30
    goodbest  
       2015-03-20 10:51:31 +08:00
    碰到按代码行数算工作量的公司,你们就老老实实写lz的吧...
    blue7wings
        31
    blue7wings  
    OP
       2015-03-20 10:52:57 +08:00
    感谢以上的同学的解答。。。
    haiyang416
        32
    haiyang416  
       2015-03-20 10:56:41 +08:00
    @b821025551b 不要误导别人,print 是语言结构。
    blue7wings
        33
    blue7wings  
    OP
       2015-03-20 10:59:55 +08:00
    我还是决定使用if,else。不必太过于强求简洁,可读性也是非常重要的。。。
    c742435
        34
    c742435  
       2015-03-20 11:00:30 +08:00
    我一般只是用&& 确保值存在。
    比如
    callback && callback();
    其他的用法,过于依赖&& 和|| 当流程跳转,会降低代码可读性。
    k9982874
        35
    k9982874  
       2015-03-20 11:02:08 +08:00 via iPad
    @ALeo +1 不加花括号不能忍

    @griffinqiu 虽然实现优美简洁但是不适合在多人项目中使用。满篇这种写法其他维护和检查的同事会想死。

    @blue7wings 综上ifelse还是最优雅的
    b821025551b
        36
    b821025551b  
       2015-03-20 11:06:10 +08:00
    @griffinqiu
    @killerand1983
    @ETiV

    这个写法绝对有问题啊,你们自己看看
    function A(){
    echo 'A';
    return true;
    }
    function B(){
    echo 'B';
    }
    true && A() || B();

    //结果:A

    function A(){
    echo 'A';
    return false;
    }
    function B(){
    echo 'B';
    }
    true && A() || B();

    //结果 AB

    function A(){
    echo 'A';
    return true;
    }
    function B(){
    echo 'B';
    }
    false && A() || B();
    //结果B
    hooluupog
        37
    hooluupog  
       2015-03-20 11:08:49 +08:00
    要么使用Fp语言,要么就忍受大量的if else。三目运算符用多了也出问题,比如多层的嵌套。
    if else {} ; 这些看起来像是噪音,不过可读性还是不错的。
    b821025551b
        38
    b821025551b  
       2015-03-20 11:09:42 +08:00
    @haiyang416 对,我错了,print是语言结构,但是它有返回值,所以能在三元里执行
    griffinqiu
        39
    griffinqiu  
       2015-03-20 11:30:00 +08:00
    @b821025551b 咳咳,本着对科学的严谨性。本PHPer决定修改该写发。
    $is_false && ($this->rollback() || true) || $this->commit();
    Registering
        40
    Registering  
       2015-03-20 11:47:36 +08:00
    clean code 中建议拆成两个方法,,,忘记了是不是,,
    155
        41
    155  
       2015-03-20 11:53:15 +08:00
    $method = $is_false ? 'rollback' : 'commit';

    $this->$method();
    jon
        42
    jon  
       2015-03-20 12:01:41 +08:00
    @griffinqiu 这个改进不错,保证条件为真时,不会执行else部分代码

    不过一般还是用ifelse这种可读性好点的
    shyangs
        43
    shyangs  
       2015-03-20 12:04:52 +08:00
    @griffinqiu
    看←_←
    Felldeadbird     44
    Felldeadbird  
       2015-03-20 12:30:25 +08:00
    最讨厌这种不加 括号的语句了。调试不好调。看着也不爽。
    ETiV
        45
    ETiV  
       2015-03-20 13:01:00 +08:00
    @b821025551b 你没考虑优先级的问题

    把括号加进去, 像这样: (xx && yy) || zz

    你是不是能看明白点?
    fr0m
        46
    fr0m  
       2015-03-20 13:16:59 +08:00
    @griffinqiu readability diaobaole
    b821025551b
        47
    b821025551b  
       2015-03-20 13:24:33 +08:00
    @ETiV xx为真,yy为假,括号里为假,会执行zz,这样会导致yy和zz都被执行 :)@griffinqiu 在39楼的改进版才是正确的
    ETiV
        48
    ETiV  
       2015-03-20 13:28:36 +08:00
    @b821025551b

    好吧, 我懂了. 咱俩说岔了!!!
    chmlai
        49
    chmlai  
       2015-03-20 14:37:30 +08:00
    不用改!
    charle9
        50
    charle9  
       2015-03-20 15:08:19 +08:00
    @mcfog +1
    ioth
        51
    ioth  
       2015-03-20 15:10:22 +08:00
    php也想优雅?
    py笑了。
    php就比c难看那么一点,当年才愿意用pascal不用c
    c就是合适懒人。
    recall704
        52
    recall704  
       2015-03-20 15:11:04 +08:00
    do_rollback() if is_false else do_commit()

    python 的写法
    loryyang
        53
    loryyang  
       2015-03-20 17:28:25 +08:00   1
    优雅不是说代码量少,而是容易看懂,层次结构合理清洗,所以不仅要这么写,而且要加上大括号。
    fxxkgw
        54
    fxxkgw  
       2015-03-20 18:10:11 +08:00
    $this->rollbakc() if($is_false) else $this->commit()
    python
    tinkerer
        55
    tinkerer  
       2015-03-20 21:18:53 +08:00
    @ALeo 含泪握爪。
    popoge
        56
    popoge  
       2015-03-20 21:24:00 +08:00
    @ALeo 请假这种写法效率高在哪里呢?
    jasontse
        57
    jasontse  
       2015-03-20 21:27:15 +08:00 via Android
    标题应该改成
    这种一句话的 if, else 有没有难以阅读的处理方法?
    shiny
        58
    shiny  
    PRO
       2015-03-20 21:31:16 +08:00
    这个时候总是能想起一个成语:大巧若拙
    ALeo
        59
    ALeo  
       2015-03-20 22:09:30 +08:00
    @popoge 去测试一下 if else 和三元运算的执行时间就知道了。
    rming
        60
    rming  
       2015-03-20 22:17:47 +08:00
    $method = $is_false ? "rollback" : "commit" ;
    call_user_func([$this, $method]);

    这样的写法,其实一开始我是拒绝的。。。
    gihnius
        61
    gihnius  
       2015-03-20 22:41:58 +08:00
    Lisp style:

    (if bool then else)
    (if false rollback-this commit-this)
    (if is-false (rollback this) (commit this))
    (if (false this) (rollback this) (commit this))
    znoodl
        62
    znoodl  
       2015-03-20 22:43:52 +08:00
    前几天刚写了个一行的,后来又改掉换成多行
    (a && b) || c
    a ? b : c
    这两种效果应该相同
    rushcheyo
        63
    rushcheyo  
       2015-03-20 22:45:12 +08:00
    (if (is-false) (funcall rollback) (funcall commit))
    rushcheyo
        64
    rushcheyo  
       2015-03-20 22:45:24 +08:00
    (if (is-false) (rollback) (commit))
    lujjjh
        65
    lujjjh  
       2015-03-20 22:45:51 +08:00   1
    很奇怪的事情,要优雅,为什么不用异常处理?而且居然没人提到,很多人都在单纯地“优化”这句 if。

    如果用的是 PDO 就更不可思议了,感觉没有好好看官方的例子。
    ryd994
        66
    ryd994  
       2015-03-20 22:56:35 +08:00 via Android
    if ($is_false) $this->rollback();
    else $this->commit();
    这样呢?
    用缩进,同时在同一行,不用花括号因为不可能看错
    glongzh
        67
    glongzh  
       2015-03-20 23:00:39 +08:00
    if...else不就是干这个的么。。。这都不用,那各语言的if...else是什么用途?
    solu
        68
    solu  
       2015-03-21 09:54:43 +08:00
    我也觉得直接用if else就好,如果想绕,也是可以的。

    call_user_method_array(['rollback', 'commit'][intval(boolval($is_false))], $this, []);
    Syec
        69
    Syec  
       2015-03-21 14:24:38 +08:00
    我觉得这样写就挺好呀,可读性多好
    kisshere
        70
    kisshere  
       2015-03-21 19:39:31 +08:00
    楼上的,我就不明白,一堆后端代码有啥好简化的?给自己看孤芳自赏好证明自己很牛叉,用了一堆三元运算符就是大神了?反正也没人看见你的代码,如果是js,用三元运算符之类的逼格还高点,至少还有人看得见
    picasso250
        71
    picasso250  
       2015-03-22 18:40:19 +08:00
    逻辑派:
    $ok or $db->rollback();
    $ok and $db->commit();

    动态派:
    $db->{$ok ? 'commit' : 'rollback'}();

    ps 但是我支持多行派、人能看懂派。
    picasso250
        72
    picasso250  
       2015-03-22 18:42:55 +08:00
    @lujjjh 确实,数据库操作和exception简直是绝配。
    bmy001
        73
    bmy001  
       2015-03-23 12:59:41 +08:00
    直接用三元不就好了?
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1045 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 44ms UTC 23:12 PVG 07:12 LAX 15:12 JFK 18:12
    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