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.

你对此有什么看法?


当前回答

作为附加信息,go提供了一个内置函数panic。这可以用来代替assert。如。

if x < 0 {
    panic("x is less than 0");
}

Panic将打印堆栈跟踪,因此在某种程度上它具有assert的目的。

其他回答

当我看到这个的时候,我真想踢作者的头。

我在代码中一直使用断言,并最终在编写更多代码时将它们全部替换掉。当我还没有编写所需的逻辑时,我就会使用它们,当我运行到代码时,我想要得到警告,而不是编写一个将在项目接近完成时删除的异常。

异常也更容易融入到产品代码中,这是我不喜欢的。断言比抛出新异常("一些通用的msg或'pretend i am An assert'")更容易注意到;

我更倾向于避免在调试和发布中做不同事情的代码。

但是,在一个条件下中断调试器并获得所有文件/行信息,以及确切的表达式和确切的值是有用的。

拥有一个“只在调试中评估条件”的断言可能是一种性能优化,因此,它只在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上写过更多关于这方面的内容

不,只要您按照预期使用assert,它就没有错。

也就是说,它应该用于在调试期间捕捉“不可能发生”的情况,而不是正常的错误处理。

断言:程序逻辑本身的失败。 错误处理:错误的输入或系统状态,不是由于程序中的错误造成的。

我很喜欢用断言。我发现当我第一次构建应用程序(可能是一个新的领域)时,它非常有用。我没有做非常花哨的错误检查(我认为是不成熟的优化),而是快速编码,并添加了大量断言。在我了解了更多事情的工作原理后,我重新编写并删除了一些断言并更改它们以更好地处理错误。

因为断言,我花更少的时间编码/调试程序。

我还注意到,断言可以帮助我想到许多可能破坏程序的东西。