Wstęp
Wśród wielu ciekawych języków programowania z listy TOP 60 warto wyróżnić język programowania D oraz kilka jego opisywanych tutaj cech.
Kiedy wielu programistów zmaga się z nową składnią (ang. syntax) swojego nowego języka, okazuje się, że dawno temu pewne ciekawe rozwiązania już trafiły do następcy języka C, czyli do języka D 🙂
Cechy, którymi się tutaj zajmiemy to kontrakty (czyli spolszczając to tzw. prewarunki) in
i out
oraz inwarianty
, czyli niezmienności
(ang. invariants). Nie ma w tym wielkiej magii, wystarczy poczytać przykłady kodów a od razu mamy szerszy obraz tych cech języka programowania D.
Jak wskazuje nazwa, kontrakty gwarantują nam działanie kodu i umożliwiają dodawania sprawdzeń, które weryfikują na bieżąco zakładane zasady kontraktów.
Tutaj znajdziesz porównanie języków ANSI C i języka D.
Przykład kodu z kontraktem typu IN w języku D
Kontrakty in
są używane do określenia warunków, które muszą być prawdziwe przed wykonaniem funkcji.
import std.stdio;
int divide(int numerator, int denominator)
in {
assert(denominator != 0, "Denominator must not be zero");
} body {
return numerator / denominator;
}
void main() {
writeln(divide(10, 2)); // Outputs: 5
writeln(divide(10, 0)); // Throws an assertion error
}
Przykład kodu z kontraktem typu OUT w języku D
Kontrakty out
określają warunki, które muszą być prawdziwe po wykonaniu funkcji.
import std.stdio;
int square(int x)
out (result) {
assert(result >= 0, "Result must be non-negative");
} body {
return x * x;
}
void main() {
writeln(square(5)); // Outputs: 25
writeln(square(-3)); // Outputs: 9
}
Przykład kodu z INVARIANT w języku D
Inwarianty są używane do określenia warunków, które zawsze muszą być prawdziwe dla obiektu w czasie jego życia, z wyjątkiem momentów, gdy metoda obiektu jest wykonywana.
import std.stdio;
class BankAccount {
private:
double balance;
public:
this(double initialBalance) {
balance = initialBalance;
}
void deposit(double amount)
in {
assert(amount > 0, "Deposit amount must be positive");
} body {
balance += amount;
}
void withdraw(double amount)
in {
assert(amount > 0, "Withdrawal amount must be positive");
assert(balance >= amount, "Insufficient balance");
} body {
balance -= amount;
}
double getBalance() const {
return balance;
}
invariant {
assert(balance >= 0, "Balance must be non-negative");
}
}
void main() {
auto account = new BankAccount(100.0);
account.deposit(50.0);
writeln("Balance after deposit: ", account.getBalance()); // Outputs: 150.0
account.withdraw(30.0);
writeln("Balance after withdrawal: ", account.getBalance()); // Outputs: 120.0
account.withdraw(200.0); // Throws an assertion error (Insufficient balance)
}
Podsumowanie Programowania Kontraktowego w języku D
- Prewarunki (
in
): Warunki, które muszą być prawdziwe przed wykonaniem funkcji. - Postwarunki (
out
): Warunki, które muszą być prawdziwe po wykonaniu funkcji. - Inwarianty: Warunki, które zawsze muszą być prawdziwe dla obiektu, z wyjątkiem momentów, gdy metoda obiektu jest wykonywana.
Te przykłady ilustrują, jak używać programowania kontraktowego w D, aby tworzyć bardziej niezawodny i samoopisujący się kod. Mam nadzieję, że zainteresowałem Ciebie ciekawymi zasadami w języku programowania D.
Oczywiście język D posiada swój kompilator również na systemie operacyjnym Linux!