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

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

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

    如题。

    特别是在需要 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 跳出去(滑稽
    LevineChen
        22
    LevineChen  
       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
    DOLLOR
        36
    DOLLOR  
       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   ·   实用小工具   ·   2563 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 05:23 · PVG 13:23 · LAX 21:23 · JFK 00:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.