do{}while(false) 这么使用上瘾了 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
814084764
V2EX    程序员

do{}while(false) 这么使用上瘾了

  •  1
     
  •   814084764 2018-06-06 17:19:14 +08:00 9149 次点击
    这是一个创建于 2691 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题。

    特别是在需要 return 的函数里面,真 TM 爽!

    46 条回复    2018-06-07 19:34:49 +08:00
    Akiyu
        1
    Akiyu  
       2018-06-06 17:21:24 +08:00
    不懂什么意思, 直接在 do while 里面写 false
    不就和没有写循环控制语句一样么
    rootx
        2
    rootx  
       2018-06-06 17:22:21 +08:00 via iPhone
    怎么个爽法
    sun1991
        3
    sun1991  
       2018-06-06 17:22:40 +08:00   1
    @Akiyu 循环只执行一次, 但是中间可以跳出该循环
    jjianwen68
        4
    jjianwen68  
       2018-06-06 17:24:35 +08:00
    没明白好处
    opengps
        5
    opengps  
       2018-06-06 17:24:56 +08:00
    我也没看懂,需要跳出时候跟直接 return 有啥区别?
    ysc3839
        6
    ysc3839  
       2018-06-06 17:29:05 +08:00 via Android
    第一次见这种用法好像是在微软的代码里?因为返回之前要释放一些资源,所以不能直接 return。
    也有不用这种写法直接用 goto 的,但是 goto 只有 C/C++ 可以用。
    ChristopherWu
        7
    ChristopherWu  
       2018-06-06 17:30:15 +08:00   1
    一般是 用在宏里面吧?
    remarrexxar
        8
    remarrexxar  
       2018-06-06 17:30:41 +08:00   4
    是不是这个意思
    do{

    blockA

    if(...){
    break;
    }

    blockB

    }while(false)

    blockC

    blockA 执行后满足某条件则不执行 blockB,直接执行 blockC,类似于 goto 的作用
    kran
        9
    kran  
       2018-06-06 17:31:08 +08:00 via iPhone
    解决代码嵌套很管用
    c3824363
        10
    c3824363  
       2018-06-06 17:33:01 +08:00
    goto 就挺好
    有些语言自以为去掉 goto 就不会产生非常混乱的代码了
    wplct
        11
    wplct  
       2018-06-06 17:36:25 +08:00
    为啥不再定义个方法?
    grantonzhuang
        12
    grantonzhuang  
       2018-06-06 17:38:13 +08:00 via Android
    @remarrexxar 大 js 的立即执行函数也可以这么搞
    ryd994
        13
    ryd994  
       2018-06-06 17:43:03 +08:00 via Android
    所以啊,实际上 goto 该用还是得用
    而且你这样也只能考虑一种 bailout
    实际上还会遇到多层嵌套的情况,比如到一半的时候拿了 xx 锁,过了一会又拿了 yy 内存。如果只有一层 bailout 的话就只能在出口判断自己要不要释放。
    有 goto 的话加一个 cleanup xx 的 label 就好
    zhuangzhuang1988
        14
    zhuangzhuang1988  
       2018-06-06 17:44:45 +08:00
    有好看的异常不用 用这货。
    ryd994
        15
    ryd994  
       2018-06-06 17:46:28 +08:00 via Android
    等等,没有 goto 的语言一般是有 throw catch exception 的。用 exception 来代替的好处是,可以不用一层层检查返回值,直接扔给上层。用 goto 退的话,你还是跑不掉要检查返回
    reself
        16
    reself  
       2018-06-06 18:24:21 +08:00
    看是啥语言。貌似还能对付宏定义的问题
    Mitt
        17
    Mitt  
       2018-06-06 18:28:55 +08:00 via iPhone
    @zhuangzhuang1988 异常代价高啊
    notreami
        18
    notreami  
       2018-06-06 18:31:24 +08:00
    想不明白,什么场景非要这样写,大部分语言都有对应的跳出当前代码块
    cuzfinal
        19
    cuzfinal  
       2018-06-06 18:41:46 +08:00
    菜鸡前端无法理解
    jiang42
        20
    jiang42  
       2018-06-06 18:47:07 +08:00 via iPhone
    C 里头宏的一种惯用法
    xiangyuecn
        21
    xiangyuecn  
       2018-06-06 18:50:42 +08:00
    前端后端习惯性使用 while(true){........; break;}, 你这个少 3 个字符, 算你牛

    套一层之后的最大好处是,不支持 goto、break 的代码段,可以随意 break 跳出去(滑稽
    Enivel
        22
    Enivel  
       2018-06-06 19:03:20 +08:00
    return early 的一种写法, 多个 return 会使代码变得混乱, 通过 do while 进行流程控制可以 做到一个入口 一个出口. 而且可以避免 if else 嵌套 阻止箭头形代码的形成. 好处多的数不过来 大家了解一下吧
    Loren
        23
    Loren  
       2018-06-06 19:29:55 +08:00 via Android
    C 语言的宏里也常用
    bumz
        24
    bumz  
       2018-06-06 19:42:35 +08:00
    ```
    a();

    do {
    b();
    if (c()) break;
    d();
    } while (false);

    e();
    ```

    等价于

    ```
    a();
    b();
    if (!c()) {
    d();
    }
    e();
    ```

    但前者更令人费解
    hsuan
        25
    hsuan  
       2018-06-06 20:03:30 +08:00 via Android
    C 里非常常见的写法,居然这么多人不知道?看来 C 真是没落了。
    VDimos
        26
    VDimos  
       2018-06-06 20:27:36 +08:00 via Android
    让我想起了 react 里面的用抛出错误的方式中断,有种异曲同工之妙
    thedrwu
        27
    thedrwu  
       2018-06-06 20:33:30 +08:00 via Android   2
    在古老的 C 技巧中常常用来写在宏里当作简单而正确的的 inline (比如 linux 内核中)

    若是如楼上所说用作 break,那一般是编码有问题,应该试着把其中内容封装成一个函数。装成函数还能有利于单元测试。
    iceheart
        28
    iceheart  
       2018-06-06 20:56:45 +08:00 via Android
    直接用 lambda 会更爽
    fuxiuyin
        29
    fuxiuyin  
       2018-06-07 00:42:20 +08:00 via iPhone
    这算是 goto 吧
    takeoffyoung
        30
    takeoffyoung  
       2018-06-07 00:45:01 +08:00
    @ysc3839 golang 的 defer 就是为这个需求量身定做
    mon6912640
        31
    mon6912640  
       2018-06-07 01:36:48 +08:00 via Android
    感谢,学到了一个实用技巧,真是巧妙
    redsonic
        32
    redsonic  
       2018-06-07 02:03:50 +08:00
    竟然这么多人不知道,记得是内核开发面试必问的一道题。。
    FrankFang128
        33
    FrankFang128  
       2018-06-07 02:36:08 +08:00
    还不如 goto 好读……
    guanhui07
        34
    guanhui07  
       2018-06-07 08:25:44 +08:00
    虽然我也喜欢用 goto ,很多企业 不会让用 goto 吧 -
    wanderpoet
        35
    wanderpoet  
       2018-06-07 08:30:01 +08:00 via iPhone
    对于 goto 的因噎废食真是够了 滥用当然不行 但也没必要一刀切的禁用 goto
    AV1
        36
    AV1  
       2018-06-07 08:32:47 +08:00   1
    @xiangyuecn JS 有可读性更好的方法……

    // Using a labeled block with break
    foo: {
    console.log('face');
    break foo;
    console.log('this will not be executed');
    }
    console.log('swap');

    // this will log:

    // "face"
    // "swap
    ytlm
        37
    ytlm  
       2018-06-07 08:44:30 +08:00
    在某些情况下这种写法还是比较有用处的
    grewer
        38
    grewer  
       2018-06-07 09:36:01 +08:00
    在 do 里面的 break 相当于一个匿名函数的 return
    dychenyi
        39
    dychenyi  
       2018-06-07 09:37:03 +08:00
    @LevineChen 对的, 这种函数开始是初始化,最后是析构,释放内存的代码,如果写 return,相当于每一个 return 前都要释放
    des
        40
    des  
       2018-06-07 09:38:32 +08:00 via Android
    @DOLLOR lint 默认禁止这么用
    xiangyuecn
        41
    xiangyuecn  
       2018-06-07 09:57:19 +08:00
    @DOLLOR #36 第一次见到这个语法 只知道 for while 可以用标签 js 果然厉害 学习了
    twotiger
        42
    twotiger  
       2018-06-07 11:26:42 +08:00
    class MyException(Exception):
    pass

    try:
    print('a1')
    raise MyException()
    print('a2')
    except MyException:
    pass

    print('a3')

    那么在 python 里面是这种写法么?
    还是经验太少了,没发现有什么亮点
    stackexplode
        43
    stackexplode  
       2018-06-07 11:32:18 +08:00
    这么经典的安全资源释放方法居然那么多人不知道,还批判了起来
    dbpe
        44
    dbpe  
       2018-06-07 11:34:25 +08:00
    不是很理解...中午去跟一下...
    814084764
        45
    814084764  
    OP
       2018-06-07 11:35:04 +08:00
    @twotiger 这个本来就不是一个 exception。。还有 exception 有性能问题吧? java 中有。不知道 python 中有没有。
    Menci
        46
    Menci  
       2018-06-07 19:34:49 +08:00 via Android
    @twotiger 异常得多写不少代码吧
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2668 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 37ms UTC 09:16 PVG 17:16 LAX 02:16 JFK 05: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