Dの契約プログラミングはコードベースが期待通りに振る舞うことを確実にする サニティ・チェックを反映させることによりコードの質を向上させることができる 言語構成体群を含みます。契約はデバッグモードでのみ利用でき、 リリースモードでは実行されません。したがってユーザの入力を 検証するのに使われてはいけません。
assertDの最も単純な契約プログラミングの形はassert(...)式で、
これは一定の条件を満たすかをチェックし、
そうでない場合はAssertionErrorでプログラムを中断します。
assert(sqrt(4) == 2);
// 任意のカスタムアサーションエラーメッセージ
assert(sqrt(16) == 4, "sqrt is broken!");
inとoutで入力パラメータと関数の返値の契約を形式化することができます。
long square_root(long x)
in {
assert(x >= 0);
} out (result) {
assert((result * result) <= x
&& (result+1) * (result+1) > x);
} do {
return cast(long)std.math.sqrt(cast(real)x);
}
inブロックの中のコンテンツは関数の本文中に表現することもできますが、
この方法のほうが意図が明確です。outブロックの中で関数の返値は
out(result)でキャプチャしそこで検証されます。
invariant()はstructやclass型の特殊なメンバ関数で、
オブジェクトのライフタイム全体におけるその状態のサニティ・チェックを行うものです:
invariant()はメンバ関数を抜けたあとに呼ばれます。
すべての契約はリリースビルドで削除されるため、ユーザ入力は契約を使って検証されるべきではありません。
加えて(訳注:例外ではなく)致命的なErrorsを投げるため、assertはnothrow関数で使うことができます。
実行時のassertの類似物はstd.exception.enforceで、
これはキャッチできるExceptionsを投げます。