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.

你对此有什么看法?


当前回答

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

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

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

其他回答

简短的回答:不,我相信断言可能有用

不,去做和断言都不是坏事。但两者都可能被误用。

Assert用于完整性检查。如果它们不正确,就会杀死程序。不是为了验证或替换错误处理。

如果您所谈论的断言意味着程序抛出然后存在,那么断言可能非常糟糕。这并不是说它们总是错误的使用,它们是一种很容易被误用的结构。他们也有很多更好的选择。这样的事情很容易被称为邪恶。

例如,第三方模块(或任何模块)几乎不应该退出调用程序。这并没有给调用程序的程序员任何控制程序此时应该承担的风险。在许多情况下,数据是如此重要,即使保存损坏的数据也比丢失数据要好。断言可能会迫使您丢失数据。

断言的一些替代方法:

使用调试器, 控制台/数据库/其他日志 异常 其他类型的错误处理

参考:

http://ftp.gnu.org/old-gnu/Manuals/nana-1.14/html_node/nana_3.html http://www.lenholgate.com/blog/2005/09/assert-is-evil.html Go不提供断言,并且有很好的理由:http://golang.org/doc/faq#assertions http://c2.com/cgi/wiki?DoNotUseAssertions

甚至主张assert的人也认为它们应该只用于开发而不是生产:

http://codebetter.com/gregyoung/2007/12/12/asserts-are-not-evil/ http://www.codeproject.com/Articles/6404/Assert-is-your-friend http://parabellumgames.wordpress.com/using-asserts-for-debugging/

This person says that asserts should be used when the module has potentially corrupted data that persists after an exception is thrown: http://www.advogato.org/article/949.html . This is certainly a reasonable point, however, an external module should never prescribe how important corrupted data is to the calling program (by exiting "for" them). The proper way to handle this is by throwing an exception that makes it clear that the program may now be in an inconsistent state. And since good programs mostly consist of modules (with a little glue code in the main executable), asserts are almost always the wrong thing to do.

是的,断言是邪恶的。

它们通常用于应该使用正确错误处理的地方。从一开始就要习惯编写正确的产品质量错误处理程序!

通常它们会妨碍编写单元测试(除非您编写了与测试工具交互的自定义断言)。这通常是因为它们被用于应该使用正确错误处理的地方。

大多数情况下,它们是从发布版本中编译出来的,这意味着当你运行实际发布的代码时,它们的“测试”是不可用的;考虑到在多线程情况下,最糟糕的问题通常只出现在发布代码中,这可能很糟糕。

有时,他们是一个拐杖,否则破碎的设计;也就是说,代码的设计允许用户以一种不应该被调用的方式调用它,而断言“阻止”了这一点。修改设计!

早在2005年,我就在我的博客http://www.lenholgate.com/blog/2005/09/assert-is-evil.html上写过更多关于这方面的内容

我从不使用assert(),示例通常是这样的:

int* ptr = new int[10];
assert(ptr);

这很糟糕,我从来没有这样做过,如果我的游戏分配了一堆怪物怎么办?为什么我要让游戏崩溃,相反,你应该优雅地处理错误,所以可以这样做:

CMonster* ptrMonsters = new CMonster[10];
if(ptrMonsters == NULL) // or u could just write if(!ptrMonsters)
{
    // we failed allocating monsters. log the error e.g. "Failed spawning 10 monsters".
}
else
{
    // initialize monsters.
}