600 likes | 745 Views
A D programozási nyelv. Bevezetés. Amiről ma szó lesz… Miért D? Mert a fejlesztők úgy látták, hogy a C++-on van még mit javítani. Mert a programozók a nyelvnek általában elszigetelt részeit használják csak. Mert a gyakran használt típusok (string, vector) nem a nyelv részei.
E N D
Bevezetés • Amiről ma szó lesz… • Miért D? • Mert a fejlesztők úgy látták, hogy a C++-on van még mit javítani. • Mert a programozók a nyelvnek általában elszigetelt részeit használják csak. • Mert a gyakran használt típusok (string, vector) nem a nyelv részei. • Mert a fordítók ma már okosabbak.
A D fő céljai • Gyakran használt funkciókat a nyelv részévé tenni. • Több paradigma támogatása • Egyszerűsítés, hogy könnyebb legyen • Hasonlítson a C++-hoz • Könnyű legyen fordítóprogramokat írni a nyelvhez • Contract-ok és unit-tesztek • Dokumentálás könnyítése
Megtartott funkciók • A kinézet • Procedurális, objektum-orientált és template-(meta)programozás támogatása • Kivételek (try-catch-finally) • Futásidejű típusazonosítás • Operátor túlterhelés • RAII • „down and dirty programming” ~ „architektúraközli programozás”
Elhagyott funkciók • Kompatibilitás C/C++-szal • Link kompatibilitás C++-szal • C preprocesszor • Többszörös öröklődés • Névterek • Forward deklaráció • Includefiles(nem kell mindig újraparszolni az egész include-ot, hanem be tudja tölteni a kész szimbólumtáblát) • Nem-virtuális tagfüggvények • 16-bites kompatibilitás
Utasítások, vezérlési szerkezetek
Kifejezések • C/C++ -hoz hasonló • Értékadó operátor kifejezés • Kifejezések részkifejezéseinek kiértékelése általában tetszőleges sorrendben történhet • Logikai kiefejezések balról jobbra, rövidre zárva • Feltételes kifejezések C/C++ -hoz hasonlóan • (log kif) ? expression : expression; • Cast-olás: cast (type) expression
Utasítások • If, for, while, switch: C/C++ -hoz hasonló • Switch –ben string-et is használhatunk • Foreach utasítás
Objektumorientáltság • Nincs többszörös öröklődés • Interface-ek bevezetése • Minden osztály az Object-ből származik • Minden függvény virtuális (kivéve static/final) • Vannak zárt osztályok • Az osztály referencia
Konstruktorok • Minden adattag automatikusan inicializálódik • A már megírt konstruktor használható • Példányosítás a new kulcsszóval • A a = new A(3); class A { this(int y) { } } class B : A { int j; this() { ... super(3); // call base constructor A.this(3) ... } }
Destruktorok • GC hívja meg (általában)
Beágyazott osztályok classOuter { classInner { } staticclassSInner { } } voidfunc() { classNested { } Outer o = newOuter; // Ok Outer.Inner oi = newOuter.Inner; // Error, no 'this' forOuter Outer.SInneros = newOuter.SInner; // Ok Nested n = newNested; // Ok }
Operátor túlterhelés • Operátor, opfunc • Op a a.opfunc();
Bináris operátor túlterhelés • a op b a.opfunc(b); • VAGY b.opfunc_r(a);
Resource Acquisition Is Initialization Kezdeti értékadás == Az erőforrás megszerzése A C++ módszer erőforrások kezelésére GC szép és jó, de használhatatlanná teszi az RAII-t RAII
Erőforrás-kezelés C#-ben • IDisposeable interfész, Dispose() függvény
Végül: RAII D-ben • Garbage Collection van • Objektumok a heap-en jönnek létre, nincs explicit élettartamuk • Try/finally –t is használhatunk erőforrás kezelésre • RAII támogatása: scope attribútum
Scope Guard statements • scope(exit)NonEmptyOrScopeBlockStatement • scope(success)NonEmptyOrScopeBlockStatement • scope(failure)NonEmptyOrScopeBlockStatement
Általában • Bevezettek több fajta függvényt • Függvényeket lehet egymásba ágyazni • Függvényekre bevezették az invariáns fogalmát • Delegátok • Inline függvények
Függvényliterálok int function(char c) fp; void test() { static intfoo(char c) { return 6; } fp = &foo; } int function(char c) fp; void test() { fp = function int(char c) { return 6;} ; }
Függvényliterálok folytatás int abc(int delegate(long i)); void test() { int b = 3; int foo(long c) { return 6 + b; } abc(&foo); } int abc(int delegate(long i)); void test() { int b = 3; abc( delegate int(long c) { return 6 + b; } ); } // no referencetoreturnvalue intabc(int delegate(long i)); void test() { int b = 3; abc( (long c) { return 6 + b; } ); }
Beágyazott függvnyek int bar(int a) { int foo(int b) { int abc() { return 1; } return b + abc(); } return foo(a); } void test() { int i = bar(3); // i is assigned 4 }
Beágyazott függvények – tulajdonságok • A beágyazott függvények csak a scope-jukban érhetők el. • A beágyazott függvények elérik a beágyazó változóit és módosíthatják is őket. • Beágyazott függvény lehet member-ben is, de az osztály nem statikus adattagjait nem éri el • Buktató: beágyazott függvények nem hivatkozhatnak egymásra (követező dia)
Buktató void test() { voidfoo() { bar(); } // error, barnotdefined void bar() { foo(); } // ok } //megoldás void test() { voiddelegate() fp; voidfoo() { fp(); } void bar() { foo(); } fp = &bar; }
Property függvények struct S { int m_x; @property { int x() { return m_x; } int x(int newx) { return m_x = newx; } } } voidfoo() { S s; s.x = 3; // callss.x(int) bar(s.x); // callsbar(s.x()) }
Pure függvények • Garantálja, hogy a minden futása ugyanolyan eredménnyel jár • Paraméterei • Vagy inmutable típusok • Vagy implicit azzá konvertálhatók
Ref függvények • Az alapértelmezett függvényvisszatérési érték jobbérték. • Ref kulcsszóval lehet balértékként visszaadni értéket ref int foo() { auto p = new int; return *p; } ... foo() = 3; // reference returns can be lvalues
Auto függvények • A visszatérési értéküket automatikusan ki tudja következtetni auto foo(int i) { return i + 3; // return type is inferred to be int }
Paraméterek • A paraméterek lehetnek • in, • out, • ref, • Stb: (lazy, final, const, immutable, scope) • in = const scope • out : Mindig inicializálódik! • Minősítő nélkül mutable másolat lesz a paraméter értéke
Variadic függvények • C-stílusú foo(3, 4, 5); // first variadic argument is 5 int foo(int x, int y, ...) { int z; z = *cast(int*)_argptr; // z is set to 5 } • Típusinfóval ellátott • Típusbiztos
Típusinfóval import std.stdio; class Foo { int x = 3; } class Bar { long y = 4; } void printargs(int x, ...) { writefln("%d arguments", _arguments.length); for (int i = 0; i < _arguments.length; i++) { _arguments[i].print(); if (_arguments[i] == typeid(int)) { int j = *cast(int *)_argptr; _argptr += int.sizeof; writefln("\t%d", j); } else if (_arguments[i] == typeid(long)) { … } else if (_arguments[i] == typeid(Bar)) { Bar b = *cast(Bar*)_argptr; _argptr += Bar.sizeof; writefln("\t%X", b); } else assert(0); } } void main() { Foo f = new Foo(); Bar b = new Bar(); writefln("%X", f); printargs(1, 2, 3L, 4.5, f, b); }
Típusbiztos int test() { return sum(1, 2, 3) + sum(); // returns 6+0 } int func() { int[3] ii = [4, 5, 6]; return sum(ii); // returns 15 } int sum(int[] ar ...) { int s; foreach (int x; ar) s += x; return s; }
Contract-ok long square_root(long x) in { assert(x >= 0); } out (result) { assert((result * result) <= x && (result+1) * (result+1) >= x); } body { return cast(long)std.math.sqrt(cast(real)x); }
Miért jó ez? • Egységes kinézet a contract-oknak • Tool support • A fordító jobb kódot tud generálni ezzel az információval • Könnyebb a kezelése és kikényszerítése • Az öröklődés kezelése …
Öröklődés • Member függvények esetén öröklődéskor a következő szabályok érvényesek • in contractok diszjunkciójának • out contractok konjunkciójának • kell teljesülni
Invariánsok • Lefut • Konstruktor után • Destruktor előtt • Publikus member előtt és után • Hiba esetén AssertError-t dob • Csak egy invariánsa lehet egy osztálynak • Release-re fordításnál az invariáns kód nem fordul le class Date { int day; int hour; invariant() { assert(1 <= day && day <= 31); assert(0 <= hour && hour < 24); } }
Unit tesztek • Nyelvi támogatásuk van • Osztályok speciális tagfüggvényei, osztályonként csak egy • Statikus inicializálás után, main előtt futnak le • A fordító a release fordításnál kihagyja a unit tesztek fordítását
Tömbök típusai • Pointerek • int* p; • Statikus tömbök • int[3] s; • Dinamikus tömbök • int[] s;
Deklaráció int[] a; // dynamic array of ints int[4][3] b; // array of 3 arrays of 4 ints each int[][5] c; // array of 5 dynamic arrays of ints int*[]*[3] d; // array of 3 pointers to dynamic arrays of pointers to ints int[]* e; // pointer to dynamic array of ints