Dで条件を「強制」するか、条件を「アサート」するかを選択するのに苦労しています(ただし、これは言語に依存しません)。
理論的には、アサーションを使用してバグを見つけ、他の条件を適用して非定型の条件をチェックすることを知っています。たとえば、メソッドの引数について言うかもしれませんassert(count >= 0)
。これは、呼び出し元にバグがあることを示しているためです。これはenforce(isNetworkConnected)
バグではないため、これは、あなたのコントロールを超えた正当な状況。
さらに、アサーションは、副作用なしに最適化としてコードから削除できますが、強制は常に条件コードを実行する必要があるため、削除することはできません。したがって、メソッドへの最初のアクセスで自分自身を埋める怠惰なコンテナを実装している場合は、enforce(!empty())
代わりに言います。これは、内部のコードを怠惰に実行するため、常にassert(!empty())
チェックが行われる必要があるためです。empty()
だから私は彼らが意味することになっていることを知っていると思います。しかし、理論は実践よりも簡単で、実際に概念を適用するのに苦労しています。
次のことを考慮してください。
他の2つの範囲を反復処理する範囲(イテレーターと同様)を作成し、結果を追加します。(機能プログラマーの場合: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
}
...
これはアサーションまたは強制のどちらである必要がありますか?パスはユーザーからのものである可能性があります(したがって、バグではない可能性があります)が、パスが有効であることがこのメソッドの前提条件です。主張または強制しますか?
ありがとう!