我很难选择是否应该在 D 中“强制”一个条件或“断言”一个条件。(不过,这与语言无关。)
从理论上讲,我知道您使用断言来查找错误,并强制执行其他条件以检查非典型条件。例如,您可能会说assert(count >= 0)
为您的方法提供一个参数,因为这表明调用者存在错误,并且您会说enforce(isNetworkConnected)
,因为那不是错误,它只是您假设的东西,这很可能不是真的超出您控制范围的合法情况。
此外,断言可以作为优化从代码中删除,没有副作用,但不能删除强制执行,因为它们必须始终执行其条件代码。因此,如果我正在实现一个惰性填充容器,它在第一次访问它的任何方法时填充自己,我说enforce(!empty())
而不是assert(!empty())
,因为检查empty()
必须总是发生,因为它惰性地执行内部代码。
所以我想我知道他们应该是这个意思。但是理论比实践容易,我很难实际应用这些概念。
考虑以下:
我正在制作一个迭代其他两个范围的范围(类似于迭代器),并添加结果。(对于函数式程序员:我知道我可以使用它map!("a + b")
,但我暂时忽略它,因为它没有说明问题。)所以我的代码在伪代码中看起来像这样:
void add(Range range1, Range range2)
{
Range result;
while (!range1.empty)
{
assert(!range2.empty); //Should this be an assertion or enforcement?
result += range1.front + range2.front;
range1.popFront();
range2.popFront();
}
}
这应该是断言还是强制执行?(范围没有同时为空是调用者的错吗?它可能无法控制范围的来源——它可能来自用户——但话又说回来,它仍然看起来像一个错误,不是吗?)
或者这是另一个伪代码示例:
uint getFileSize(string path)
{
HANDLE hFile = CreateFile(path, ...);
assert(hFile != INVALID_HANDLE_VALUE); //Assertion or enforcement?
return GetFileSize(hFile); //and close the handle, obviously
}
...
这应该是断言还是强制执行?路径可能来自用户——因此它可能不是一个错误——但它仍然是此方法的前提条件,即路径应该是有效的。我主张还是强制执行?
谢谢!