Go语言的创造者写道:
Go doesn't provide assertions. They are undeniably convenient, but our experience has been that programmers use them as a crutch to avoid thinking about proper error handling and reporting. Proper error handling means that servers continue operation after non-fatal errors instead of crashing. Proper error reporting means that errors are direct and to the point, saving the programmer from interpreting a large crash trace. Precise errors are particularly important when the programmer seeing the errors is not familiar with the code.
你对此有什么看法?
我更倾向于避免在调试和发布中做不同事情的代码。
但是,在一个条件下中断调试器并获得所有文件/行信息,以及确切的表达式和确切的值是有用的。
拥有一个“只在调试中评估条件”的断言可能是一种性能优化,因此,它只在0.0001%的程序中有用——人们知道他们在做什么。在所有其他情况下,这是有害的,因为表达式实际上可能改变程序的状态:
assert(2 == shroedingerscat . getnummears ());
会使程序在调试和发布时做不同的事情。
我们开发了一组assert宏,可以在调试版和发布版中抛出异常。例如,THROW_UNLESS_EQ(a, 20);what()消息同时包含文件、行和a的实际值,等等,将抛出异常。只有宏才有这个功能。调试器可以配置为在特定异常类型的'throw'时中断。
是的,断言是邪恶的。
它们通常用于应该使用正确错误处理的地方。从一开始就要习惯编写正确的产品质量错误处理程序!
通常它们会妨碍编写单元测试(除非您编写了与测试工具交互的自定义断言)。这通常是因为它们被用于应该使用正确错误处理的地方。
大多数情况下,它们是从发布版本中编译出来的,这意味着当你运行实际发布的代码时,它们的“测试”是不可用的;考虑到在多线程情况下,最糟糕的问题通常只出现在发布代码中,这可能很糟糕。
有时,他们是一个拐杖,否则破碎的设计;也就是说,代码的设计允许用户以一种不应该被调用的方式调用它,而断言“阻止”了这一点。修改设计!
早在2005年,我就在我的博客http://www.lenholgate.com/blog/2005/09/assert-is-evil.html上写过更多关于这方面的内容