今天在读《程序员修炼之道》一书中的 断言式编程 小节,其中提到了观点: 保持断言常开 。即断言不但要在开发和测试期间开启,在生产环境中同样要开启。
两位大师给出的理由大概是:在开发和测试期间,断言很可能不会被触发,但是在生产环境中一切皆有可能,你不能因为在开发和测试期间通过了断言,就在生产环境中把断言给去除。他们认为就算断言存在性能问题,那么也只需要关闭那些真正会影响性能的断言。
我最早是通过《代码大全 2 》中的 防御式编程 那章知道了断言,其中关于断言的一个观点是:断言主要是用于开发和维护阶段,在生成产品代码时不应该把断言编译到目标代码中,以免降低性能。后来我在 PHP 官方手册中也看到了同样的观点。这种观点已经先入为主,并且深入我心。
现在双方提出了刚好相反的观点,并且双方都是比较权威的,而我自己在断言编程这块经验又比较少,没办法自行判断该怎么做,所以:
想请问那些有思考过该问题的人,你站哪一边?站那一边的理由是什么?
希望有这块经验的人能分享下你的想法,帮助我和没这块经验的人少走一点弯路,谢谢!
1
cigarzh 2020-05-12 23:22:18 +08:00
你的程序要是高精尖行业,比如航空航天啥的,开断言也可以理解,甚至还有更变态东西来保证正确性
别的就算了吧,别给自己找不痛快 |
2
zhm1620 2020-05-12 23:34:57 +08:00 1
想象一下你半夜睡的正香,收到了一条运维发的警告告诉你服务器宕机了,你火急火燎爬起来一看,assert 。
|
3
wutiantong 2020-05-13 00:05:05 +08:00
C++有 invariant 这个概念,可以去了解一下
|
4
littlewing 2020-05-13 02:30:58 +08:00 via iPhone
那我为什么不用其他可控的异常处理方式
|
5
luozic 2020-05-13 03:20:00 +08:00 via iPhone
这种需要的是转换,在测试和 sit 环境是断言,在线上自动切换为 log to metrics 平台。当然高安全性和正确性要求的部分模块是要做形式化验证的,如果真有钱。
|
6
msg7086 2020-05-13 03:26:01 +08:00
断言一般是用在特别重大的错误上。比如系统常量被修改,或者内存存储的数据自行改变了等等,这种一出现就意味着整套系统必须停机排查的情况。
一般业务对这种要求不高吧,用异常处理我觉得够用了。 |
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 |
8
mitu9527 OP |
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 |
10
macha 2020-05-13 12:29:57 +08:00 via iPhone
我的习惯是打个 error 日志。
|
11
namelosw 2020-05-13 13:04:09 +08:00
Runtime 的 assert 其实一般叫 invariant 。比如用 React 偶尔就可以看到抛。
楼上都说当机之类的 crash,也不一定,invariant 也可以 handle,主要看目的是什么。 需要 Case by case 权衡一下一个 invariant 被破坏,到底是继续运行的损失大,还是停下来损失大。 另外就是 invariant 的另外一个目的是暴露这个问题,记下来就可以修了。 |
12
jinzhongyuan 2020-05-13 14:45:12 +08:00
我还以为是说的 Spring 提供的 Assert 呢,我心想那个好像可以随便加
|
13
vitoliu 2020-05-13 15:14:23 +08:00
业务断言的目的一般是写在特殊逻辑前,确保后续逻辑能正常运行。看个人习惯,我不经常应用,有时候改别人的代码的时候会加。
|
14
duzhanguan 2020-05-14 10:15:06 +08:00
@laike9m 你从哪找的这些博客
|
15
laike9m 2020-05-14 14:16:00 +08:00 via Android
@duzhanguan 以前看过的,不是现找的
|