关于断言的一个疑问,希望可以和懂的人讨论一下,请不吝赐教。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
mitu9527
V2EX    程序员

关于断言的一个疑问,希望可以和懂的人讨论一下,请不吝赐教。

  •  
  •   mitu9527 2020-05-12 22:39:17 +08:00 3390 次点击
    这是一个创建于 1986 天前的主题,其中的信息可能已经有所发展或是发生改变。

    今天在读《程序员修炼之道》一书中的 断言式编程 小节,其中提到了观点: 保持断言常开 。即断言不但要在开发和测试期间开启,在生产环境中同样要开启。

    两位大师给出的理由大概是:在开发和测试期间,断言很可能不会被触发,但是在生产环境中一切皆有可能,你不能因为在开发和测试期间通过了断言,就在生产环境中把断言给去除。他们认为就算断言存在性能问题,那么也只需要关闭那些真正会影响性能的断言。 我最早是通过《代码大全 2 》中的 防御式编程 那章知道了断言,其中关于断言的一个观点是:断言主要是用于开发和维护阶段,在生成产品代码时不应该把断言编译到目标代码中,以免降低性能。后来我在 PHP 官方手册中也看到了同样的观点。这种观点已经先入为主,并且深入我心。 现在双方提出了刚好相反的观点,并且双方都是比较权威的,而我自己在断言编程这块经验又比较少,没办法自行判断该怎么做,所以: 想请问那些有思考过该问题的人,你站哪一边?站那一边的理由是什么? 希望有这块经验的人能分享下你的想法,帮助我和没这块经验的人少走一点弯路,谢谢! 
    15 条回复    2020-05-14 14:16:00 +08:00
    cigarzh
        1
    cigarzh  
       2020-05-12 23:22:18 +08:00
    你的程序要是高精尖行业,比如航空航天啥的,开断言也可以理解,甚至还有更变态东西来保证正确性

    别的就算了吧,别给自己找不痛快
    zhm1620
        2
    zhm1620  
       2020-05-12 23:34:57 +08:00   1
    想象一下你半夜睡的正香,收到了一条运维发的警告告诉你服务器宕机了,你火急火燎爬起来一看,assert 。
    wutiantong
        3
    wutiantong  
       2020-05-13 00:05:05 +08:00
    C++有 invariant 这个概念,可以去了解一下
    littlewing
        4
    littlewing  
       2020-05-13 02:30:58 +08:00 via iPhone
    那我为什么不用其他可控的异常处理方式
    luozic
        5
    luozic  
       2020-05-13 03:20:00 +08:00 via iPhone
    这种需要的是转换,在测试和 sit 环境是断言,在线上自动切换为 log to metrics 平台。当然高安全性和正确性要求的部分模块是要做形式化验证的,如果真有钱。
    msg7086
        6
    msg7086  
       2020-05-13 03:26:01 +08:00
    断言一般是用在特别重大的错误上。比如系统常量被修改,或者内存存储的数据自行改变了等等,这种一出现就意味着整套系统必须停机排查的情况。
    一般业务对这种要求不高吧,用异常处理我觉得够用了。
    laike9m
        7
    laike9m  
       2020-05-13 07:33:28 +08:00   1
    断言是 assert 吗?那当然要常开了,不开的话加它干嘛。加断言是为了 fail fast,不隐藏问题。当然,因为断言一旦 fail 一般会导致整个程序挂掉,所以加断言需要谨慎,一般只加在“如果条件不满足,程序即使继续跑下去也没有意义”的地方。其它预期会出错的地方用异常来处理。

    两篇文章供参考
    http://pgbovine.net/programming-with-asserts.htm
    https://blog.regehr.org/archives/1091
    mitu9527
        8
    mitu9527  
    OP
       2020-05-13 08:35:01 +08:00
    jdhao
        9
    jdhao  
       2020-05-13 11:52:04 +08:00
    要看语言,譬如对于 Python,如果开启了 optimize 模式,那么 assert 语句是不会运行的。如果要检查某个东西是否有效,应该使用 if 加上 raise 来处理或者使用异常捕获,并不推荐使用 assert 来检查。

    参考
    1. https://stackoverflow.com/questions/5142418/what-is-the-use-of-assert-in-python
    2. https://stackoverflow.com/a/20076295/6064933
    macha
        10
    macha  
       2020-05-13 12:29:57 +08:00 via iPhone
    我的习惯是打个 error 日志。
    namelosw
        11
    namelosw  
       2020-05-13 13:04:09 +08:00
    Runtime 的 assert 其实一般叫 invariant 。比如用 React 偶尔就可以看到抛。

    楼上都说当机之类的 crash,也不一定,invariant 也可以 handle,主要看目的是什么。

    需要 Case by case 权衡一下一个 invariant 被破坏,到底是继续运行的损失大,还是停下来损失大。

    另外就是 invariant 的另外一个目的是暴露这个问题,记下来就可以修了。
    jinzhongyuan
        12
    jinzhongyuan  
       2020-05-13 14:45:12 +08:00
    我还以为是说的 Spring 提供的 Assert 呢,我心想那个好像可以随便加
    vitoliu
        13
    vitoliu  
       2020-05-13 15:14:23 +08:00
    业务断言的目的一般是写在特殊逻辑前,确保后续逻辑能正常运行。看个人习惯,我不经常应用,有时候改别人的代码的时候会加。
    duzhanguan
        14
    duzhanguan  
       2020-05-14 10:15:06 +08:00
    @laike9m 你从哪找的这些博客
    laike9m
        15
    laike9m  
       2020-05-14 14:16:00 +08:00 via Android
    @duzhanguan 以前看过的,不是现找的
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     934 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 23:00 PVG 07:00 LAX 16:00 JFK 19:00
    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