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.

你对此有什么看法?


当前回答

我承认使用了断言,但没有考虑适当的错误报告。然而,这并不意味着它们在正确使用时是非常有用的。

They are especially useful for if you want to follow the "Crash Early" principle. For example suppose you're implementing a reference counting mechanism. At certain locations in your code you know that the refcount should be zero or one. And also suppose that if the refcount is wrong the program won't crash immediately but during the next message loop at which point it will be difficult to find out why things went wrong. An assert would have been helpful in detecting the error closer to its origin.

其他回答

与其说是坏事,不如说是适得其反。永久性错误检查和调试是分开的。Assert让人们认为所有的调试都应该是永久性的,使用过多会导致大量的可读性问题。在需要时,永久错误处理应该比这种方法更好,由于assert会导致自己的错误,因此这是一种非常值得怀疑的实践。

我从不使用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.
}

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

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

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

断言并不邪恶,但很容易被滥用。我非常同意“断言经常被用作一种拐杖,以避免考虑正确的错误处理和报告”的说法。我经常看到这种情况。

就我个人而言,我确实喜欢使用断言,因为它们记录了我在编写代码时可能做出的假设。如果在维护代码时这些假设被打破了,那么可以在测试期间检测到问题。但是,在进行产品构建时(即使用#ifdefs),我确实强调要从代码中剥离出每个断言。通过剥离产品构建中的断言,我消除了任何人将其误用为拐杖的风险。

断言还有另一个问题。断言只在运行时进行检查。但是通常情况下,您想要执行的检查可以在编译时执行。最好在编译时检测问题。对于c++程序员,boost提供了BOOST_STATIC_ASSERT,它允许您执行此操作。对于C程序员,本文(链接文本)描述了一种可用于在编译时执行断言的技术。

总之,我遵循的经验法则是:不要在生产构建中使用断言,如果可能的话,只对在编译时无法验证的东西使用断言(即,必须在运行时检查)。

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