Contract programming has a longer form, see the book for more details. Here, we'll see just the shorter version. This shorter form is called expression-based contracts.
| (1) with contracts
|
import std.stdio;
int add(const int a, const int b)
in (a >= 0, "`a` cannot be negative")
in (b >= 0)
out (result; result < 1000, "the sum must be below 1000")
{
return a + b;
}
void main()
{
writeln(add(2, 4)); // 6
// writeln(add(-2, 4)); // AssertError, `a` cannot be negative
// writeln(add(995, 20)); // AssertError, the sum must be below 1000
}
|
Notes:
- With
in, you can check the input parameters.
- With
out, you can check the return value of the function. result is a common name, but you could also call it something else.
- It's very similar to asserts. You write conditions that must be true (like in an assert).
This is actually equivalent to the following:
| (2) same thing with asserts
|
int add(const int a, const int b)
{
assert(a >= 0, "`a` cannot be negative");
assert(b >= 0);
int result = a + b;
assert(result < 1000, "the sum must be below 1000");
return result;
}
|
What's the difference? In the 2nd example, asserts are mixed with the function's body. In the 1st example, contracts are kept separated from the function's block. You can use whichever you prefer.
Note:
- In release mode (
-release), contract programming features are disabled, just like the asserts. It also shows that contract programming is just a fancy way of writing asserts.