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

2020-05-12 22:39:17 +08:00
 mitu9527

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

两位大师给出的理由大概是:在开发和测试期间,断言很可能不会被触发,但是在生产环境中一切皆有可能,你不能因为在开发和测试期间通过了断言,就在生产环境中把断言给去除。他们认为就算断言存在性能问题,那么也只需要关闭那些真正会影响性能的断言。

我最早是通过《代码大全 2 》中的 防御式编程 那章知道了断言,其中关于断言的一个观点是:断言主要是用于开发和维护阶段,在生成产品代码时不应该把断言编译到目标代码中,以免降低性能。后来我在 PHP 官方手册中也看到了同样的观点。这种观点已经先入为主,并且深入我心。

现在双方提出了刚好相反的观点,并且双方都是比较权威的,而我自己在断言编程这块经验又比较少,没办法自行判断该怎么做,所以:

想请问那些有思考过该问题的人,你站哪一边?站那一边的理由是什么?

希望有这块经验的人能分享下你的想法,帮助我和没这块经验的人少走一点弯路,谢谢!
2744 次点击
所在节点    程序员
15 条回复
cigarzh
2020-05-12 23:22:18 +08:00
你的程序要是高精尖行业,比如航空航天啥的,开断言也可以理解,甚至还有更变态东西来保证正确性

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

两篇文章供参考
http://pgbovine.net/programming-with-asserts.htm
https://blog.regehr.org/archives/1091
mitu9527
2020-05-13 08:35:01 +08:00
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
2020-05-13 12:29:57 +08:00
我的习惯是打个 error 日志。
namelosw
2020-05-13 13:04:09 +08:00
Runtime 的 assert 其实一般叫 invariant 。比如用 React 偶尔就可以看到抛。

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

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

另外就是 invariant 的另外一个目的是暴露这个问题,记下来就可以修了。
jinzhongyuan
2020-05-13 14:45:12 +08:00
我还以为是说的 Spring 提供的 Assert 呢,我心想那个好像可以随便加
vitoliu
2020-05-13 15:14:23 +08:00
业务断言的目的一般是写在特殊逻辑前,确保后续逻辑能正常运行。看个人习惯,我不经常应用,有时候改别人的代码的时候会加。
duzhanguan
2020-05-14 10:15:06 +08:00
@laike9m 你从哪找的这些博客
laike9m
2020-05-14 14:16:00 +08:00
@duzhanguan 以前看过的,不是现找的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/671078

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX