Programowanie kontraktowe za pomocą kontraktów in i out oraz inwariantów w języku D

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!

TUX - maskotka systemu Linux

About the author

Autor "BIELI" to zapalony entuzjasta otwartego oprogramowania, który dzieli się swoją pasją na blogu poznajlinuxa.pl. Jego wpisy są skarbnicą wiedzy na temat Linuxa, programowania oraz najnowszych trendów w świecie technologii. Autor "BIELI" wierzy w siłę społeczności Open Source i zawsze stara się inspirować swoich czytelników do eksplorowania i eksperymentowania z kodem.