Język programowania D jest statycznie typowanym, kompilowanym językiem wieloparadygmatowym. Pierwsza stabilna wersja pojawiła się w 2007 roku i od tego czasu struktura języka dość mocno ewoluowała. Najważniejsze cechy języka wyróżniające go głównie od C++:
- prawdziwe moduły, nie ma podziału na nagłówki oraz pliki z implementacją, jednak istnieje możliwość zawarcia interface'u w osobnym pliku
- brak wielodziedziczenia, zamiast tego mamy interface'y
- statyczne
if
y, które są rozwijane w czasie kompilacji - samodzielne szablony, co w sumie pozwala na łatwe metaprogramowanie
template Factorial(ulong n) {
static if(n <= 1)
const Factorial = 1; // można zauważyć, że jeśli typ jest określony jako const to jest on określany na podstawie przypisanej wartości
else
const Factorial = n * Factorial!(n - 1);
}
- szablony są określane poprzez
!()
co pozwala uniknąć problemów jakie są w C++ np. zX< 1>2 > x1
. Jednak jeśli mamy tylko pojedynczy argument szablonu można to zapisać jakoX!my_func x
- ujednolicony zapis typów w postaci
<typ> <nazwa>
oraz brak wielowyrazowych typów jakunsigned int
, zamiast tego mamyuint
, np.
uint[] tab; // tablica liczb bez znaku
real pi = 3.14; // liczba typu rzeczywistego
MyClass my_instance; // nie tworzy jeszcze instancji, by ją stworzyć trzeba użyć new MyClass();
my_instance = new MyClass();
string str = "abba"; // string jest aliasem do immutable(char)[] przez co sama tablica jest zmienna, ale nie da się zmieniać poszczególnych znaków
char[] editable_str = str.dup; // edytowalna kopia
const E =2.7182818; // automatyczne określenie typu jako real
idouble imaginary_number = 7.4i; // wbudowane liczby urojone i zespolone
creal complex_number = 15.3 + 3.992i + imaginary_number;
- silny podział na klasy i struktury
- wbudowany Garbage Collector
- możliwość leniwej ewaluacji argumentów, np.
void my_func(int i, lazy void x) {
while(--i)
x();
}
int x = 0;
my_func(3, writeln(x++));
- wbudowane w rdzeń języka tablice asocjacyjne oraz wektory
int[string][] table;
table["abba"] = [ 1, 3, 6, 28, 46 ];
table["baba"] = [ 5, 8, 2849, 53 ];
table["abba"] ~= [ 2, 5, 7 ]; // operator ~ służy do konkatenacji tablic
- programowanie kontraktowe.
pure int f(int x)
in {
// sprawdzenie argumentów na wejściu
}
out {
// sprawdzenie wyjścia
}
body {
// ciało funkcji
}
- unit testy zawarte w bloku
unittest {}
Co sądzicie o tym wynalazku?