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.
你对此有什么看法?
这种情况经常出现,我认为让断言辩护令人困惑的一个问题是,它们通常基于参数检查。所以考虑一下这个不同的例子,当你使用断言时:
build-sorted-list-from-user-input(input)
throw-exception-if-bad-input(input)
...
//build list using algorithm that you expect to give a sorted list
...
assert(is-sorted(list))
end
您对输入使用异常是因为您预计有时会得到错误的输入。您断言对列表进行排序是为了帮助您找到算法中的bug,根据定义,这是您所不期望的。断言只存在于调试版本中,因此即使检查的开销很大,您也不介意对例程的每次调用都进行检查。
您仍然需要对产品代码进行单元测试,但这是确保代码正确的一种不同的补充方式。单元测试确保您的例程符合其接口,而断言是一种更细粒度的方法,以确保您的实现完全按照您的期望进行。
Assert非常有用,可以在出现意外错误时通过在出现问题的第一个迹象时停止程序来节省大量回溯时间。
另一方面,断言很容易被滥用。
int quotient(int a, int b){
assert(b != 0);
return a / b;
}
正确的说法应该是:
bool quotient(int a, int b, int &result){
if(b == 0)
return false;
result = a / b;
return true;
}
所以…从长远来看……从大局来看……我必须同意断言可能会被滥用。我一直都这么做。