D (limbaj de programare)

Versiunea actuală a paginii nu a fost încă examinată de colaboratori experimentați și poate diferi semnificativ de versiunea revizuită la 31 martie 2020; verificările necesită 22 de modificări .
D
Semantică multi- paradigma : imperativ , orientat pe obiecte , funcțional , contract [1] , programare generică
Clasa de limba limbaj de programare orientat pe obiecte , limbaj de programare procedural , limbaj de programare functional ,de programare generic , limbaj de programare paralel [d] , limbaj de programare multi-paradigma , limbaj de programare imperativ ,de programare compilat si limbaj de programare
Tipul de execuție compilate
Aparut in 2001
Autor Walter Bright , Andrei Alexandrescu
Dezvoltator Bright, Walter și D Language Foundation [d]
Extensie de fișier .d, .dd, .disau.def
Eliberare 2.100.2 [2]  ( 10 septembrie 2022 )
Tip sistem strict, static, cu inferență de tip
Implementări majore Digital Mars D (implementare de referință) , LDC , GDC
A fost influențat C , C++ , Python , Ruby , C# , Java , Eiffel
influențat MiniD , DScript , Vala , Qore , Swift , Genie
Site-ul web dlang.org
 Fișiere media la Wikimedia Commons

D ( Di ) este un limbaj de programare compilat multiparadigmă, tipizat static , creat de Walter Bright de la Digital Mars . Din 2006 Andrei Alexandrescu este și coautor . D este un descendent al limbajului C++ , dar a fost îmbunătățit semnificativ în comparație cu acesta. De asemenea, împrumută o serie de concepte din limbajele de programare Python , Ruby , C# , Java , Eiffel .

D este disponibil pentru sistemele de operare Windows, Linux, macOS, FreeBSD. Se lucrează la portarea pe Android [3] .

Istorie

În prefața cărții lui A. Alexandrescu Limbajul de programare D, Walter Bright scrie că a început dezvoltarea acestui limbaj în 1999. Proiectul a fost conceput ca o reinginerire a limbajului C++ pentru a scăpa de cele mai semnificative deficiențe ale limbajului original și a introduce soluții arhitecturale moderne în acesta. La crearea limbajului D, s-a încercat combinarea performanței limbajelor de programare compilate cu siguranța și expresivitatea celor dinamice .

Inițial, autorul a intenționat să numească limbajul „Marte”, dar din cauza continuității față de C++, limbajul a fost numit constant „D” în discuții, drept urmare, acest nume a fost atribuit proiectului.

Versiunea 1.0 a compilatorului stabil a fost lansată pe 2 ianuarie 2007 [4] . La scurt timp după lansarea compilatorului pe 17 iunie 2007, autorul a trecut versiunea 1 în modul suport și a început să dezvolte versiunea 2.0, care inițial nu garanta compatibilitatea cu versiunea inversă [5] . Această versiune (ultima versiune D major până în prezent) este încă în curs de dezvoltare până în prezent.

Prezentare generală a limbii

Limbajul D implementează multe caracteristici și concepte sintactice care nu se găsesc în C++: programare contractuală , teste unitare încorporate , module în loc de fișiere antet (pre-C++20), suport pentru colectarea gunoiului (în același timp menținând disponibilitatea memoriei manuale). management), matrice asociative încorporate, închideri , funcții anonime , motorul de șabloane a fost reproiectat semnificativ.

Sintaxă

D aparține familiei de limbaje asemănătoare C, în termeni generali, sintaxa sa este similară cu C/C++/C#, Java. La dezvoltarea unui limbaj se respecta principiul: codul care este egal valabil atat in C cat si in D trebuie sa se comporte in acelasi mod.

Bună lume! » către D:

import std . stdio ; void main () { writeln ( "Bună ziua, lume!" ); }

La fel ca în C, o funcție main()este un punct de intrare.

Construcțiile if, for, while, do-whilearată și funcționează similar cu C/C++. Instrucțiunea cu alegere multiplă switcharată similar cu C++, dar permite variabile în etichetele de ramuri caseși necesită ca fiecare ramură să se casetermine cu breaksau return; pentru a trece la următoarea ramură după procesarea celei curente, trebuie să utilizați construcția specială goto case. Sunt de asemenea interzise structurile switchfără ramură default.

Dintre structurile de control suplimentare, se poate observa static if - o instrucțiune pentru compilarea condiționată (condiția este verificată static și conținutul ramurii care îi corespunde este inclus în cod), operatorul complet cu alegere multiplă final switch - spre deosebire de cel obișnuit switch, acesta funcționează numai cu valorile enum, iar compilatorul verifică static dacă alegerea ia în considerare toate opțiunile posibile și dă o eroare în caz contrar. Există, de asemenea, o buclă de colectare foreach.

Modularitate

D are un sistem încorporat pentru împărțirea unui program în module (pachete), care oferă compilare separată și import-export controlat. Sistemul de pachete seamănă cu cel al Java sau Go: pachetele formează o structură ierarhică care se mapează în mod natural la arborele sistemului de fișiere. Spre deosebire de C++, D nu are un spațiu de nume global, fiecare nume este definit într-un pachet. Cu ajutorul instrucțiunii import, un modul de program poate importa un pachet, punând la dispoziție toate definițiile din acesta. Numele importate pot fi accesate cu calificarea: " имя_пакета.имя_объекта".

Limbajul oferă o serie de instrumente menite să ofere lucru convenabil cu numele importate. Este posibil să redenumiți pachetul în timpul importului, să setați un nume alternativ (alias) pachetului importat, să importați nume specifice. În plus, limbajul permite, fără instrucțiuni suplimentare, utilizarea numelor importate fără calificare prin numele pachetului. Cu toate acestea, există o limitare: dacă există mai mult de o definiție de potrivire a unui nume întâlnită în program în domeniul de aplicare, compilatorul va arunca o eroare și va solicita ca numele să fie calificat în mod explicit. Acest lucru previne așa-numita „deturpare de nume” atunci când, atunci când un pachet nou este adăugat la listele de import, compilatorul începe să asocieze un anumit nume în program cu o definiție diferită de definiția cu care a fost asociat anterior.

Sintaxă universală a apelurilor de funcție (UFCS)

D implementează mecanismul UFCS (Uniform function call syntax), care vă permite să apelați funcții pentru orice obiect ca și cum ar fi metodele acestuia. De exemplu:

import std . stdio ; import std . algoritm ; import std . matrice ; void main () { auto a = [ 2 , 4 , 1 , 3 ]; // toate cele trei dintre următoarele sunt corecte și funcționează la fel scrieln ( a ); // Versiunea „clasică” asemănătoare C a unui . scrieln (); // funcția este numită ca și cum ar fi o metodă a obiectului „a” chiar dacă nu este un . scrie ; // funcția fără parametri poate fi apelată fără paranteze // aceasta vă permite să utilizați lanțuri de apeluri care sunt specifice limbajelor funcționale int [] e = a . sortare (). invers ; // este posibilă și înlănțuirea cu mai multe linii stdin . byLine ( KeepTerminator . da ) . harta !( a => a . idup ) . matrice . sortare ; }

Atributele funcției

Funcțiile din D pot fi definite cu atribute opționale suplimentare care vă permit să specificați în mod explicit unele aspecte ale comportamentului acestor funcții. De exemplu, o funcție marcată cu atributul pur este garantată a fi pură din punct de vedere funcțional (cu unele avertismente) [6] . Puritatea funcțională este verificată în timpul compilării. Un exemplu de declarație de funcție cu un atribut:

pur int sum ( int primul , int al doilea ) { return first + second ; } int sum ( int primul , int al doilea ) pur // atributele pot fi specificate si dupa lista de argumente { return first + second ; }

Exemple de atribute de funcție:

  • pur - puritate funcțională
  • @safe - o garanție a funcționării în siguranță a memoriei
  • nothrow - funcția este garantată să nu arunce excepții
  • @nogc - garantează că funcția nu conține operațiuni care alocă memorie pe garbage collector
  • @property este un atribut al unei metode de clasă care evită utilizarea getters-setters „naivi”

Calcul paralel

Limbajul are un mecanism încorporat pentru lansarea subproceselor paralele folosind o funcție încorporată spawn()și schimbul de date între fragmente de cod executate în paralel prin transmiterea de mesaje (funcții send()și receive()/ receiveTimeout()). Utilizarea mesajelor este considerată de către autorii lui D a fi preferabilă schimbului de date prin intermediul memoriei partajate.

Cu toate acestea, în cazurile în care acest lucru este necesar (de exemplu, atunci când se transferă cantități mari de date între corutine), este posibil să se folosească abordarea tradițională pentru limbaje imperative cu zone de memorie partajată și sincronizarea accesului prin semafoare și mutexuri . Pentru a sprijini un astfel de schimb:

  • folosind un modificator shared, datele partajate între fire pot fi declarate, în timp ce încercările de a lucra cu aceste date cu operații non-atomice sunt blocate la nivel de compilator;
  • biblioteca de limbi oferă primitive de sincronizare standard;
  • biblioteca de limbaj oferă clase speciale de blocare care sunt utilizate pentru blocarea contextului : declararea unei instanțe a unei astfel de clase într-o metodă sincronizează codul din acel punct până la sfârșitul metodei;
  • folosind modificatorul sincronizat, puteți declara o întreagă clasă sincronizată : toate metodele acestei clase sunt sincronizate automat de către compilator, astfel încât să nu poată fi executate două dintre ele în paralel pentru aceeași instanță a unei clase declarate ca partajate.

Pentru toate instrumentele de sincronizare încorporate, compilatorul monitorizează și interzice automat încercările de modificare a datelor nepartajate în cadrul codului sincronizat care este accesibil de mai mult de un fir.

Teste unitare încorporate

În D, testele unitare fac parte din limbaj și pot fi utilizate fără biblioteci sau cadre suplimentare.

import std . stdio ; int first ( int [] arr ) { return arr [ 0 ]; } unittest { int [] arr1 = [ 1 , 2 , 3 ]; int [] arr2 = [ 10 , 15 , 20 ]; assert ( primul ( arr1 ) == 1 ); assert ( primul ( arr2 ) == 10 ); } void main () { // ... }

Paradigma de programare

D implementează cinci paradigme principale de programare - imperativ , OOP , metaprogramare , programare funcțională și calcul paralel ( model actor ).

Managementul memoriei

D folosește un colector de gunoi pentru gestionarea memoriei, cu toate acestea, controlul manual este posibil și folosind supraîncărcarea operatorului newși delete, precum și utilizarea malloc și free , similar cu C. Colectorul de gunoi poate fi pornit și oprit manual, puteți adăuga și elimina memorie zone de vizibilitate, pornirea forțată a procesului de asamblare parțial sau complet. Există un manual detaliat care descrie diferite scheme de gestionare a memoriei în D pentru cazurile în care colectorul de gunoi standard nu este aplicabil.

SafeD

SafeD este numele unui subset al limbajului D, a cărui utilizare garantează siguranța accesului la memorie .

Tipuri de date

Limbajul are un set bogat de tipuri de date definite și facilități pentru definirea de noi tipuri. Tipurile din limbajul D sunt împărțite în tipuri de valori și tipuri de referință.

Tipuri de bază

Setul de tipuri de bază poate fi împărțit în următoarele categorii [7] :

  • void - tip special pentru valori goale
  • bool - tip boolean
  • tipuri de întregi: semnate byte, short, int, longși corespunzătoare lor nesemnate ubyte, ushort, uint,ulong
  • tipuri de virgulă mobilă: float, double, real. Pentru tipurile în virgulă mobilă, există variante corespunzătoare pentru numerele imaginare și complexe :
    • imaginar: ifloat, idouble,ireal
    • complex: сfloat, сdouble,сreal
  • tipuri de semne (caractere): char, wchar, dchar, care denotă unitățile de cod ale codificărilor UTF-8, UTF-16 și, respectiv, UTF-32.

Spre deosebire de C++, toate dimensiunile tipurilor întregi sunt definite de specificație. Adică, tipul int va fi întotdeauna de 32 de biți. Literale întregi pot fi scrise în zecimală, binară (prefixată cu 0b) și hexazecimală (prefixată cu 0x). Notația în stil C a literalelor în octal (adică, prefixată cu 0) a fost eliminată, deoarece este ușor de confundat o astfel de notație cu zecimală. Dacă tot trebuie să utilizați sistemul octal, puteți utiliza șablonul std.conv.octal .

Tipuri derivate
  • pointer - indicator
  • array - matrice
  • associative array - tablou asociativ
  • function - functie
  • delegate - delegat
  • string, wstring, dstring sunt aliasuri convenabile pentru matrice imuabile de tipuri (caracter) semnate și immutable(char)[], care denotă șiruri Unicode imuabile ( calificator imuabil ) într-una dintre codificările UTF-8, UTF-16 și, respectiv, UTF-32.immutable(wchar)[]immutable(dchar)[]
Tipuri personalizate
  • alias - pseudonim
  • enum - enumerare
  • struct - structura
  • union - o asociere
  • class - Clasa
Tip inferență, cuvinte cheie „auto”, „typeof” și fără nume („Voldemort”)

D are un mecanism de inferență de tip. Aceasta înseamnă că tipul, de regulă, poate fi calculat în timpul compilării și nu trebuie să fie specificat în mod explicit. De exemplu, expresia: auto myVar = 10va fi convertită în int myVar = 10. Utilizarea inferenței de tip are mai multe avantaje:

  • Cod mai concis și mai ușor de citit, mai ales dacă folosește o structură lungă sau nume de clasă. De exemplu, expresia

VeryLongTypeName var = VeryLongTypeName(/* ... */);

poate fi înlocuit cu

auto var = VeryLongTypeName(/* ... */);

  • folosind cuvântul cheie typeof , puteți crea o variabilă de același tip ca o variabilă existentă, chiar dacă tipul acesteia este necunoscut. Exemplu:
// fisier1.d int var1 ; // file2.d typeof ( var1 ) var2 ; // var2 primește tipul int
  • utilizarea de tipuri anonime. Exemplu:
// Funcția returnează de fapt un rezultat de tipul TheUnnameable, dar deoarece acest tip este definit în interiorul funcției, // nu îl putem seta în mod explicit ca tip de returnare. // Totuși, putem seta tipul de returnare la „auto”, lăsând compilatorul să-și dea seama de el însuși auto createVoldemortType ( int value ) { struct TheUnnameable { int getValue () { return value ; } } returnează TheUnnameable (); }

Tipurile fără nume sunt denumite informal tipuri Voldemort, după Voldemort ( "El-Cine-Nu-Trebuie-Fie-Numit"), principalul antagonist al seriei Harry Potter [8] . Inferența tipului nu trebuie confundată cu tastarea dinamică , deoarece, deși tipul nu este specificat în mod explicit, este calculat în timpul compilării, nu în timpul executării.

Implementări

  • DMD  - Digital Mars D ( VIKI ), un compilator de referință dezvoltat de Walter Bright. Acest compilator implementează cel mai complet standardul de limbaj, suportul pentru toate inovațiile apare în primul rând în el. Partea frontală și cea din spate ( [1] ) sunt distribuite sub licența Boost .
  • LDC  - DMD ( WIKI ) - front-end pentru LLVM ( SITE )
  • GDC  - DMD ( VIKI ) - front-end pentru compilatorul GCC
  • LDC pentru iOS  — set de instrumente bazat pe LDC pentru compilarea încrucișată cu iOS
  • D pentru Android  (link indisponibil)  - Set de instrumente pentru compilarea încrucișată cu Android (x86 folosind DMD și ARM folosind LDC )
  • SDC (Stupid D Compiler)  este un compilator experimental (compilator ca bibliotecă) care utilizează LLVM ca back-end și nu se bazează pe DMD.
  • Calypso  - LDC furk care oferă interoperabilitate Clang directă, permițând utilizarea directă a anteturilor C.
  • MicroD  - DMD furk care scoate codul sursă C în loc de fișiere obiect
  • DtoJS  - DMD furk care scoate codul sursă JavaScript în loc de fișiere obiect
  • D Compiler for .NET  - Un back-end pentru compilatorul limbajului de programare D 2.0 [9] [10] . Compilează codul în limbajul intermediar comun (CIL) bytecode, mai degrabă decât în ​​codul mașinii. CIL poate fi apoi rulat printr-o mașină virtuală Common Language Infrastructure (CLR) .
  • DIL este o implementare a compilatorului realizată manual pentru limbajul de programare D scris în D v2 folosind biblioteca standard Tango . Lexerul și analizatorul sunt implementate complet. Se lucrează la analiza semantică. Backend-ul va fi cel mai probabil LLVM .

Instrumente și instrumente de dezvoltare

IDE-uri și editori

Suport pentru D în diferite IDE-uri , implementat folosind plugin-uri:

IDE conecteaza Platforme
IntelliJ IDEA DLanjă multiplatformă
Eclipsă DDT multiplatformă
MonoDevelop/Xamarin Mono-D multiplatformă
Studio vizual Vizual-D Windows
Codul Visual Studio Cod-D multiplatformă
xcode D pentru Xcode Mac OS X
Zeus IDE D pentru Zeus IDE Windows

IDE-uri native pentru limbajul D:

  • Coeditare (Windows, Linux)
  • DLangIDE (Windows, Linux, OS X) - construit pe D în sine, acceptă evidențierea sintaxelor, completarea codului, DUB, diverse compilatoare, depanare și multe altele.

D este suportat de multe editoare de text: Vim, Emacs, Kate, Notepad++, Sublime Text, TextMate și altele [11] .

Manager de pachete

DUB este managerul oficial de pachete pentru D. DUB acționează ca un depozit de pachete și este folosit pentru gestionarea dependențelor și, de asemenea, ca sistem de compilare. Setul de dependențe, metadatele despre proiect și steagurile compilatorului sunt stocate în format JSON sau SDL. Exemplu de fișier proiect simplu (JSON):

{ "name" : "myproject" , "description" : "Un mic serviciu web de-al meu." , "authors" : [ "Peter Parker" ], "homepage" : "http://myproject.example.com" , "license" : "GPL-2.0" , "dependencies" : { "vibe-d" : " ~>0.7.23" } }

Utilități și instrumente

rdmd  este un utilitar care vine cu compilatorul DMD care vă permite să compilați și să rulați fișiere sursă D din mers. Acest lucru permite D să fie utilizat pentru programe mici într-un mod similar cu bash, perl și python:

// myprog.d # !/ usr / bin / env rdmd import std . stdio ; void main () { writeln ( "Bună ziua, lume cu script automat care rulează!" ); }

Apelarea comenzii ./myprog.dîn consolă va compila și executa automat programul.

DPaste [12]  este un serviciu online pentru rularea programelor D într-un browser, similar cu serviciile JSBin și CodePen .

run.dlang.io [13]  este un compilator și dezasamblator online.

Utilizare, distribuire

Distribuția limbajului D este limitată, dar este utilizat pentru dezvoltarea reală a software-ului industrial. Site-ul oficial [14] oferă o listă de 26 de companii care utilizează cu succes D în dezvoltarea de sisteme software care operează într-o varietate de domenii, inclusiv programare de sistem, proiecte web, jocuri și motoare de jocuri, software pentru calcule științifice, utilități pentru diverse scopuri. , si asa mai departe. Limbajul D este promovat, în special, de D Language Foundation, o organizație publică care promovează limbajul D în sine și software- ul open source creat folosindu-l.

Potrivit indicelui TIOBE , interesul maxim pentru D s-a manifestat în perioada 2007-2009, în martie 2009 indicele limbajului D a ajuns la 1,8 (locul 12), care este maximul său absolut. După o scădere în prima jumătate a anilor 2010, până în 2016 a ajuns la o stare relativ stabilă - valoarea numerică a indicelui fluctuează în intervalul 1,0-1,4, în clasament limba se află în al treilea zece. În ratingul de popularitate , compilat pe baza rezultatelor agregarii datelor privind posturile vacante pentru dezvoltatori, limbajul D nu este inclus nici în lista principală (top-20) nici în generală (top-43), ceea ce indică o cerere scăzută în rândul angajatorilor.

Exemple de cod

Exemplul 1

Bună lume! »

import std . stdio ; void main () { writeln ( "Bună ziua, lume!" ); }

Exemplul 2

Un program care imprimă argumentele liniei de comandă cu care a fost apelat

import std . stdio : writefln ; void main ( string [] args ) { foreach ( i , arg ; args ) writefln ( "args[%d] = '%s'" , i , arg ); }

Exemplul 3

Un program care citește o listă de cuvinte dintr-un fișier linie cu linie și scoate toate cuvintele care sunt anagrame ale altor cuvinte

import std . stdio , std . algoritm , std . interval , std . șir _ void main () { dstring [][ dstring ] semne2cuvinte ; foreach ( dchar [] w ; linii ( Fișier ( „words.txt” ))) { w = w . chomp (). toLower (); cheie imuabilă = w . dup . sortare (). eliberare (). idup ; semne2cuvinte [ cheie ] ~= w . idup ; } foreach ( cuvinte ; semne2cuvinte ) { if ( cuvinte . lungime > 1 ) { writefln ( cuvinte . join ( " " )); } } }

Vezi și

  • Marte digital
  • Pentru o comparație a caracteristicilor lui D cu alte limbaje, consultați Comparația limbajelor de programare (sintaxă)

Note

  1. Descrierea implementării paradigmei de programare a contractelor în limbajul Dee . Arhivat din original pe 3 ianuarie 2014.
  2. Jurnal de modificări: 2.100.2 .
  3. Forumul de discuții pentru limbajul de programare D pentru Android - D . Preluat la 7 iunie 2015. Arhivat din original la 21 mai 2015.
  4. DMD 1.00 - iată-l! (digitalmars.D.announce) Arhivat pe 5 martie 2007 la Wayback Machine 
  5. Jurnalul modificărilor D 2.0 (link descendent) . Preluat la 11 ianuarie 2009. Arhivat din original la 1 iunie 2012.    (Engleză)
  6. Funcții - Limbaj de programare D . Consultat la 17 iunie 2015. Arhivat din original pe 17 iunie 2015.
  7. Tipuri - Limbaj de programare D . Preluat la 7 iunie 2015. Arhivat din original la 17 mai 2015.
  8. Tipurile Voldemort în D | Dr. Dobb . Consultat la 8 iunie 2015. Arhivat din original pe 19 iunie 2015.
  9. Arhiva CodePlex . Arhiva CodePlex. Consultat la 16 februarie 2018. Arhivat din original la 26 ianuarie 2018.
  10. Sursa pentru compilatorul D.NET este acum disponibilă . InfoQ. Consultat la 16 februarie 2018. Arhivat din original la 30 noiembrie 2018.
  11. Editors-D Wiki . Data accesului: 16 iunie 2015. Arhivat din original pe 3 iulie 2015.
  12. Dpaste (downlink) . Consultat la 16 iunie 2015. Arhivat din original pe 6 iulie 2015. 
  13. run.dlang.io . Preluat la 23 septembrie 2019. Arhivat din original la 24 decembrie 2019.
  14. Organizații care folosesc limbajul D. dlang.org. Preluat la 7 octombrie 2019. Arhivat din original la 6 august 2019.

Literatură

Link -uri


,