D (limbaj de programare)

De la Wikipedia, enciclopedia liberă.
Salt la navigare Salt la căutare
D.
limbaj de programare
D Limbaj de programare logo.svg
Autor Walter Bright , Andrei Alexandrescu
Data de origine 2001 [1]
Ultima versiune 2.086.0 [2]
Paradigme programare funcțională , programare imperativă și programare orientată pe obiecte
Extensii comune .d
Influențată de C, C ++, C #, Eiffel, Java, Python, Ruby
A influențat MiniD, DScript, Vala, Qore, Swift
Implementare referință
Sistem de operare Unix-like (FreeBSD, Linux etc.), Windows, MacOS X și 11
Licență GPL / Artistic (frontend DMD),

Boost (biblioteci standard și runtime), sursă disponibilă (backend DMD), sursă complet deschisă (LDC și GDC)

Site-ul web dlang.org

Limbajul de programare D s-a născut în decembrie 1999 din mintea lui Walter Bright .

Este un object- orientat limbaj, și ar putea fi definit ca o evoluție a C și limbajul C ++ , remarcandu - se de la aceste limbi , cu următoarele caracteristici: gestionare mai simplă a claselor și șabloane decât C ++, un colector de gunoi ca în Java , suport pentru RTTI ( informații despre tipul de execuție ), introducerea tipului întreg pe 128 de biți (neutilizabil încă), o gestionare a modulului similară cu cea a Python în locul fișierelor antet, matrici asociative (în plus față de pointerul clasic- stil, static, dinamic) și multe altele. De asemenea, permite apelarea API-ului Windows și apelarea funcțiilor scrise în C (folosind cuvântul cheie extern).

În prezent, îl puteți utiliza pentru sistemele Windows , Linux x86 și PPC , macOS , AIX și FreeBSD printr-un frontend de compilator GCC numit GDC. Pe Windows este de preferat să folosiți DMD.

Originea numelui și a istoriei

D este un limbaj de programare creat de DigitalMars; numele provine din faptul că a provenit dintr-o re-inginerie C ++, făcându-l un limbaj pe care D istingue. Obiectivul său este de a atinge puterea și performanța ridicată a limbajelor de nivel scăzut, dar cu o mare productivitate și portabilitate ușoară a limbajelor de nivel înalt, cum ar fi C , C ++ , C #, Java , Perl , Python , Ruby și asemenea. În special, sintaxa și caracteristicile tehnice ale compilatorului se bazează pe C / C ++ , C # și Java.

Caracteristicile compilatorului

Compilatorul D este structurat într-un mod diferit de limbile principale, moștenind puncte forte și creând un limbaj extrem de original. Printre cele mai importante caracteristici, ne amintim

  • Mai rapid de compilat, mai rapid decât Java și C ++
  • Utilizarea colectorului de gunoi .NET și Java - dar în general mult mai puțin eficientă
  • Se bazează pe o bibliotecă nativă numită Phobos, bogată în funcții (acceptă socket, thread, zip, base64 , funcții Linux, funcții Windows, md5), suportă și biblioteca C direct. De multe ori astăzi multe proiecte folosesc o bibliotecă externă numită Tango, creată și întreținută de comunitatea D.
  • Compilatorul recunoaște codul HTML prezent în codul sursă, ignorându-l și permițând în continuare compilarea (foarte util pentru documentarea unui program, crearea unei forme de programare alfabetizată)
  • În ciuda asemănărilor cu C # și Java, nu este nevoie să instalați interpreți separat, tot ce aveți nevoie este în binar fără a lua o dimensiune enormă.
  • Există un compilator pentru Win32 și Linux pe x86 , dar pe Sourceforge există un proiect numit GDC, care acceptă și alte sisteme de operare
  • Codul acceptă coduri de stil sh, astfel încât fișierele sursă să poată începe pe unix cu #! / usr / bin / dmd -run de exemplu

Unele caracteristici

Funcții imbricate

Ca și în Pascal, o funcție poate conține la rândul său declarațiile altor funcții, respectând în același timp regulile generale de aplicare pentru utilizarea lor. Un exemplu:

 voo foo () {
   nul A () {
     B (); // Bine
     C (); // eroare, C nedefinit
   }
   gol B () {
       nul C () {
           nul D () {
               A (); // Bine
               B (); // Bine
               C (); // Bine
               D (); // Bine
           }
       }
   }
   A (); // Bine
   B (); // Bine
   C (); // eroare, C nedefinit
 }

Funcția cea mai interioară are acces la toate funcțiile externe, dar o funcție externă nu poate accesa funcțiile interne ale unei funcții interne. Ordinea funcțiilor este, de asemenea, critică. Alt exemplu:

 test nul () {
    void foo () { bar (); } // eroare, bara nedefinită
    void bar () { foo (); } // ok
 }

Se poate vedea că apelul de funcție reciprocă nu este posibil, deoarece în compilarea foo () bara de funcții nu a fost încă definită. Soluția din D este de a utiliza delegați (care sunt diferiți de delegații C #):

 test nul ()
 {
    void delegate () fp ;
    voo foo () { fp (); }
    void bar () { foo (); }
    fp = & bar ;
 }

O altă caracteristică este că o funcție imbricată poate accesa câmpurile celei externe, dacă funcția este statică, câmpul trebuie să fie și static.

În versiunea experimentală 2.07, închiderile reale au fost introduse în limbaj.

Litere funcționale

Acest lucru vă permite să creați un indicator de funcție sau să delegați direct într-o expresie, deci în loc să faceți acest lucru:

 funcția int ( char c ) fp ; // declarați un pointer de funcție

 test nul () {
    static int foo ( char c ) { return 6 ; }

    fp = & foo ;
 }

o poți face așa:

 funcția int ( char c ) fp ;

 test nul () {
    fp = function int ( char c ) { return 6 ; };
 }

Acest lucru se aplică și delegaților, astfel încât să puteți utiliza acest cod:

 test dublu () {
    dublu d = 7,6 ;
    plutitor f = 2,3 ;

    bucla void ( int k , int j , declarația void delegate () ) {
    for ( int i = k ; i < j ; i ++)
        statement ();
    }

    bucla ( 5 , 100 , delegat { d + = 1 ; } );
    bucla ( 3 , 10 , delegat { f + = 1 ; } );

    returnează d + f ;
 }

Tablouri redimensionabile

Tablourile sunt implementate cu caracteristici noi comparativ cu cele în stil C și C ++ (în C ++, cu toate acestea, caracteristici similare sunt disponibile folosind containere STL ). Prin câmpul de lungime este posibil să accesați dimensiunea unei matrice și să o redimensionați, fără a recurge la alocarea dinamică, cum ar fi new, malloc și realloc.

 int [] matrice ;
 în timp ce ( 1 ) {
    c = getinput ();
    dacă (! c )
       pauză ;
    matrice . lungime = matrice . lungime + 1 ;
    matrice [ matrice . lungime - 1 ] = c ;
 }

Feliere

Vă permite să creați o nouă referință la un subarray. Sintaxa sa este:

 int [ 10 ] a ; // declara matrice de 10 int
 int [] b ;

 b = a [ 1..3 ]; // a [1..3] este o matrice de 2 elemente, a [1] și a [2]
 foo ( b [ 1 ]); // echivalent cu foo (0)
 a [ 2 ] = 3 ;
 foo ( b [ 1 ]); // echivalent cu foo (3)

Tablouri asociative

De asemenea, numite hărți sau dicționare în alte limbi, vă permit să asociați valoarea unui element dintr-o matrice unui alt tip de date sau obiect, astfel încât să putem avea:

 int [ char []] b ; // matrice asociativă b de inți care sunt
                   // indexat de o serie de caractere.
                   // KeyType este char []
 b [ "salut" ] = 3 ; // setați valoarea asociată tastei „salut” la 3
 func ( b [ "salut" ]); // treceți 3 ca parametru la func ()
 ...
 int * p ;
 p = ( „salut” în b );
 if ( p ! = nul )
 printf (* p );
 b . remove ( „salut” );
 ...

Tipuri puternice

Să luăm în considerare următorul alias:

 alias int myint;

Este posibil să declarați o funcție care ia int ca argument și apoi să-i transmiteți un myint fără ca compilatorul să genereze o eroare: adică compilatorul este capabil să rezolve referințele alias în tipuri de date fundamentale.

Dacă, pe de altă parte, doriți ca o funcție să accepte numai și întotdeauna un int și, prin urmare, typedef - urile trebuie considerate ca fiind diferite tipuri de date, puteți utiliza instrucțiunea typedefs în locul aliasurilor. De exemplu:

 typedef int myint;

Folosirea myint într-o funcție care acceptă un int va da o eroare de compilare. De asemenea, este posibil să creați tipuri de defecte cu valori afișate constant:

 typedef int myint = 9718;
myint i; // inițializat la 9718

Mixin

Un mixin vă permite să obțineți un set de declarații dintr-un șablon specificat și să le stocați în altă parte.

 Șablon Foo () {
    int x = 5 ;
 }

 mixin Foo ;

 struct Bar {
    mixin Foo ;
 }

 test nul () {
    printf ( "x =% d \ n" , x ); // tipărește 5
    { Bara b ;
    int x = 3 ;

    printf ( "bx =% d \ n" , b . x ); // tipărește 5
    printf ( "x =% d \ n" , x ); // tipărește 3
    {
        mixin Foo ;
        printf ( "x =% d \ n" , x ); // tipărește 5
        x = 4 ;
        printf ( "x =% d \ n" , x ); // tipărește 4
    }
    printf ( "x =% d \ n" , x ); // tipărește 3
    }
    printf ( "x =% d \ n" , x ); // tipărește 5
 }

Acest lucru se aplică și funcțiilor:

 Șablon Foo () {
    void func () { printf ( "Foo.func () \ n" ); }
 }

 clasa Bar {
    mixin Foo ;
 }

 Codul clasei : Bar {
    void func () { printf ( "Code.func () \ n" ); }
 }

 test nul () {
    Bar b = Bar nou ();
    b . func (); // apelează Foo.func ()

    b = Cod nou ();
    b . func (); // apelează Code.func ()
 }

Pot specifica tipul șablonului

 Foo ( T ) { șablon
    T x = 5 ;
 }

 mixin Foo ! ( int ); // creați x de tip int

și iată un ultim exemplu:

 șablon duffs_device ( alias id1 , alias id2 , alias s ) {
    void duff_loop () {
    if ( id1 < id2 ) {
        typeof ( id1 ) n = ( id2 - id1 + 7 ) / 8 ;
        comutare (( id2 - id1 ) % 8 )
        {
        caz 0 : do { s ();
        caz 7 : s ();
        cazul 6 : s ();
        cazul 5 : s ();
        cazul 4 : s ();
        caz 3 : s ();
        cazul 2 : s ();
        cazul 1 : s ();
                  } while (- n > 0 );
        }
    }
    }
 }

 void foo () { printf ( "foo \ n" ); }

 test nul () {
    int i = 1 ;
    int j = 11 ;

    mixin duffs_device ! ( i , j , delegate { foo (); } );
    duff_loop (); // execută foo () de 10 ori
 }

Static Dacă

Dacă staticul a fost conceput pentru a înlocui directivele preprocesorului. Această afirmație evaluează o expresie la momentul compilării, fără a crea un nou domeniu. Un exemplu:

 const int i = 3 ;
 int j = 4 ;

 static if ( i == 3 ) // ok, la sfera modulului
    int x ;

 clasa C {
    const int k = 5 ;
    static if ( i == 3 ) // ok
    int x ;
    altceva
    lung x ;

    static if ( j == 3 ) // eroare, j nu este o constantă
    int y ;

    static dacă ( k == 5 ) // ok, k se află în domeniul de aplicare curent
    int z ;
 }

 șablon INT ( int i ) {
    static if ( i == 32 )
    alias int INT ;
    altfel static if ( i == 16 )
    alias scurt INT ;
    altceva
    afirmare statică ( 0 ); // nu sunt acceptate
 }

 INT ! ( 32 ) a ; // a este un int
 INT ! ( 16 ) b ; // b este un scurt
 INT ! ( 17 ) c ; // eroare, declanșări statice de afirmare

În consecință, există și o afirmare statică. În D, există modalități de a executa funcții simple de compilare, folosind sintaxa normală, fără a recurge la șabloane ca în C ++.

Expresii de identitate

Vă permite să verificați identitățile a două obiecte cu operatorul is sau! Is (care nu este este). Apoi verificați, de exemplu pentru obiecte, dacă sunt aceeași instanță, pentru matrice dacă conțin aceleași elemente etc. Este utilizat în principal pentru verificarea omogenității între 2 obiecte.

Inferație de tip implicită

Folosind auto, un tip de variabilă poate fi implicit într-o atribuire.

 static x = 3 ; // x este tip int
 auto y = 4u ; // y este tip uint
 auto s = "șir" ; // s este de tip char [6]

 clasa C { ... }

 auto c = C nou (); // c este un handle pentru o instanță din clasa C

Programarea contractelor

Programarea contractelor este excelentă pentru evitarea erorilor. O condiție este verificată la intrarea în funcție și la ieșire, apoi se verifică o cerință pentru executarea corpului și returnează rezultatul numai dacă condiția este adevărată. Este prezent și în limba Eiffel

 rădăcină pătrată lungă ( lung x )
    in {
        afirmă ( x > = 0 );
    }
    afară ( rezultat ) {
        afirmă (( rezultat * rezultat ) == x );
    }
    corp {
        întoarce matematica . sqrt ( x );
    }

Există, de asemenea, posibilitatea de a defini invarianții de clasă, care sunt verificați în afara metodelor. Adică, afirmații de atribut care trebuie întotdeauna verificate (dar acest tip de invariant de clasă nu este încă cel mai bine tratat în prezența moștenirii).

Test de unitate

Acestea sunt utile pentru a vă asigura că funcționează codul. De fapt, evită, atunci când este folosit pentru a testa clase, să creeze un fișier sursă cu in main (), să instanțeze clasa, să-l folosească. Este posibil, în D, să procedați după cum urmează:

 clasa Suma {
    int add ( int x , int y ) { return x + y ; }

    unittest {
        Sum sum = new Sum ;
        afirmați ( suma . adăugați ( 3 , 4 ) == 7 );
        afirmă (sumă. add (- 2, 0) == - 2);
    }
 }

 void main () {
 }

Pentru a rula astfel de teste unitare, trebuie să furnizați compilatorului parametrul -unittest

Declarația domeniului de aplicare

Este folosit pentru a executa o funcție la ieșirea dintr-un scop (indiferent dacă există sau nu erori), la ieșirea cu erori și la ieșirea fără erori, iată un exemplu (rețineți că acestea sunt executate invers, de jos în sus):

Un exemplu simplu este acesta:

 writef ( "1" );
 {
    writef ( "2" );
    scope ( exit ) writef ( "3" );
    scope ( exit ) writef ( "4" );
    writef ( "5" );
 }
 writefln ();

care tipărește 4321

Acesta este un exemplu puțin mai complex:

 clasa Foo {
    this () { writef ( "0" ); }
    ~ this () { writef ( "distrus" ); }
 }

 incearca {
    scope ( exit ) writef ( "2" );
    scop ( succes ) writef ( "3" );
    auto Foo f = Foo nou ();
    scop ( eșec ) writef ( "4" );
    aruncă o excepție nouă ( „msg” );
    scope ( exit ) writef ( "5" );
    scop ( succes ) writef ( "6" );
    scop ( eșec ) writef ( "7" );
 }
 catch ( Excepția e ) {
 }
 writefln ();

tipărirea 0412

Controlul alinierii membrilor structurilor

Vă permite să specificați alinierea membrilor unei structuri, cu o sintaxă similară cu aceasta:

 align ( 1 ) struct S {
    octet a ; // plasat la offset 0
    octet [ 3 ] filler1 ;
    octet b ; // plasat la offset 4
    octet [ 3 ] umplutură2 ;
 }

Notă

  1. ^ Schimb de modificări - Limbaj de programare D 1.0 - Digital Mars , pe Digital Mars . Adus 25-07-2014 .
  2. ^ Schimbare jurnal - Limbaj de programare D , pe limbajul de programare D. Adus 28-07-2017 .

linkuri externe

  • Site oficial , pe dlang.org . Editați pe Wikidata
Controlul autorității LCCN (EN) sh2010005564 · GND (DE) 7606805-5
Informatică Portal IT : accesați intrările Wikipedia care se ocupă cu IT