Siirry sisältöön

D-ohjelmointikieli: C++-yhteensopiva, muistiturvallinen järjestelmäkieli

D-ohjelmointikieli: C++-yhteensopiva järjestelmäkieli, joka yhdistää C++-tason suorituskyvyn, muistiturvallisuuden ja modernin ilmaisuvoiman.

D-ohjelmointikieli on oliosuuntautunut, imperatiivinen, moniparadigmainen järjestelmäohjelmointikieli. D-kieli on syntynyt C++:n uudelleensuunnitteluna, ja D:n suunnittelutavoitteet pyrkivät yhdistämään käännettyjen kielten suorituskyvyn ja nykyaikaisten dynaamisten kielten turvallisuuden ja ilmaisuvoiman. D-koodi on yleisesti yhtä nopeaa kuin vastaava C++-koodi, mutta samalla lyhyempää ja muistiturvallisempaa.

 

Lyhyt historia ja tavoitteet

D syntyi 2000-luvun alussa tarkoituksena säilyttää C++:n suorituskyky ja järjestelmäohjelmoinnin ominaisuudet, mutta poistaa kielen monimutkaisuutta ja lisätä turvallisuutta sekä tuottavuutta. Sen suunnittelussa on otettu vaikutteita monista kielistä (esim. C, C++, Java, Python ja Lisp), ja tavoitteena on tarjota moderni työkalu sekä järjestelmä- että sovelluskehitykseen.

Keskeiset ominaisuudet

  • Moniparadigmaisuus: tuki olio-ohjelmoinnille, funktionaalisille piirteille, imperatiiviiselle tyylille ja metaohjelmoinnille.
  • Suorituskyky: käännetty kieli, jonka koodi voi olla lähestulkoon yhtä nopeaa kuin C/C++-vastineet.
  • Muistiturvallisuus: kielessä on työkaluja ja attribuutteja muistivirheiden vähentämiseksi (esim. @safe, @trusted, @system, @nogc).
  • Metaohjelmointi ja CTFE: laajat compile-time -ominaisuudet, kuten template-mallinnus, mixinit ja CTFE (compile-time function execution).
  • Modernit kielenrakenteet: moduulit korvaavat header-tiedostot, sopimukset (contracts), lambdat, toutitteluominaisuudet ja heikennetty syntaksi verrattuna perinteiseen C++:iin.

Muistiturvallisuus ja muistin hallinta

D tarjoaa useita mekanismeja muistiturvallisuuden parantamiseksi ilman, että suorituskykyä joudutaan luopumaan:

  • @safe / @trusted / @system: funktioattribuutit, jotka ohjaavat koodin turvallisuustasoa ja rajoittavat epävarmoja operaatioita.
  • Garbage Collector (GC): D:n runtime sisältää roskankerääjän, mikä helpottaa muistin hallintaa ja vähentää muistivuotoja. GC on kuitenkin valinnainen: järjestelmäohjelmoinnissa voi kirjoittaa @nogc-koodia ja käyttää manuaalista muistinhallintaa tai RAII-tyyppisiä ratkaisuja.
  • Array bounds checking ja tyyppijärjestelmä: oletuksena saatavilla olevat tarkistukset ja immutability- ja const-avainsanat vähentävät yleisiä virheitä.
  • Deterministinen siivous: destruktorit ja scope-ominaisuudet (esim. scope(exit)) mahdollistavat resurssien vapauttamisen ennustettavasti.

Metaohjelmointi ja generics

D:ssä on tehokkaat generics- ja metaohjelmointiominaisuudet: templatet, compile-time -funktiot (CTFE), string-mixinit, reflektio ja traitit mahdollistavat monimutkaisen koodin tuottamisen turvallisesti ja ilman runsaasti boilerplatea. Tämä tekee D:stä erityisen sopivan tilanteisiin, joissa suorituskyky ja koodin abstraktion taso molemmat ovat tärkeitä.

Yhteensopivuus ja ekosysteemi

  • C-yhteensopivuus: D tukee hyvin C-funktioiden kutsumista ja kirjastojen linkittämistä (extern(C)), mikä tekee olemassa olevan C-koodin hyödyntämisestä helppoa.
  • C++-yhteensopivuus: D:n suunnittelussa on ollut vaikutteita C++:sta ja kielellä on mekanismeja rajalliseen C++-yhteensopivuuteen (esim. extern(C++)), mutta täydellinen saumaton interoperabiliteetti riippuu ABI:sta ja käytetyistä C++-ominaisuuksista.
  • Komppailijat ja työkalut: tunnetuimpia kääntäjiä ovat DMD (referenssikääntäjä), GDC (GCC:n D-portti) ja LDC (LLVM-pohjainen). Paketinhallinta- ja build-työkalu on dub, ja standardikirjasto on nimeltään Phobos (ja runtime druntime).

Konkurenssi ja rinnakkaisuus

D tarjoaa useita tapoja toteuttaa rinnakkaisuutta ja turvallista monisäikeisyyttä: immutability (immutable), shared-tyyppi sekä korkeamman tason kirjastoja kuten std.concurrency ja std.parallelism. Ohjelmoija voi valita säie- tai viestipohjaisen mallin tilanteen mukaan.

Käyttötapaukset

D soveltuu erityisesti niihin projekteihin, joissa tarvitaan natiivin koodin suorituskykyä mutta halutaan myös moderneja tuottavuutta parantavia ominaisuuksia. Tyypillisiä käyttökohteita ovat järjestelmäohjelmointi, pelimoottorit, palvelinpuolen sovellukset, tietojenkäsittelykirjastot ja työkalu- tai infrastruktuurikehitys.

Yhteenveto

D on tavoitteellinen kompromissi suorituskyvyn ja turvallisuuden välillä: se tarjoaa C/C++-tyyppisen suorituskyvyn, mutta runsaasti moderneja kieliominaisuuksia, muistiturvallisuutta parantavia mekanismeja ja tehokasta metaohjelmointia. Valitsemalla D:n kehittäjä saa työkalun, jolla voi kirjoittaa tehokasta, selkeämpää ja turvallisempaa natiivikoodia—samalla kuitenkin säilyttäen mahdollisuuden integroida olemassaolevia C- ja joissain tilanteissa C++-resursseja.

Esimerkkejä

Esimerkki 1

Tämä esimerkkiohjelma tulostaa komentoriviargumentit. Main-funktio on D-ohjelman aloituskohta, ja args on joukko merkkijonoja, jotka edustavat komentoriviargumentteja. D:ssä merkkijono on merkkijono, jota D1:ssä edustaa char[] ja D2:ssa immutable(char)[].

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

foreach-lause voi iteroida mitä tahansa kokoelmaa. Tässä tapauksessa se tuottaa indeksin (i) ja arvon (arg) sarjan args. Indeksin i ja arvon arg tyyppi on johdettu array argsin tyypistä.

Esimerkki 2

Seuraavassa esitellään useita D-ominaisuuksia ja D-suunnittelun kompromisseja hyvin lyhyessä ohjelmassa. Se käy läpi words.txt-nimisen tekstitiedoston rivit, joissa on eri sana jokaisella rivillä, ja tulostaa kaikki sanat, jotka ovat muiden sanojen anagrammeja.

import std. stdio, std. algorithm, std. range, std. string; void main() { dstring[][dstring] signs2words; foreach(dchar[] w; lines(File("words.txt"))))     { w = w. chomp(). toLower(); immutable key = w. dup. sort(). release(). idup; signs2words[key] ~= w. idup; } foreach(words; signs2words) if(words. length > 1) writefln(words. join(" ")); }
  1. signs2words on sisäänrakennettu assosiatiivinen matriisi, joka yhdistää dstring-avaimet (32-bittiset / char-avaimet) dstring-matriiseihin. Se on samanlainen kuin defaultdict(list) Pythonissa.
  2. lines(Tiedosto()) tuottaa rivit laiskasti, rivinvaihdon kanssa. Sen jälkeen se on kopioitava idup-ominaisuudella, jotta saadaan merkkijono, jota käytetään assosiatiivisen array-joukon arvoina (arrayjen idup-ominaisuus palauttaa muuttumattoman duplikaatin arraysta, mikä on tarpeen, koska dstring-tyyppi on itse asiassa immutable(dchar)[]). Sisäänrakennetut assosiatiiviset matriisit vaativat muuttumattomat avaimet.
  3. Operaattori ~= liittää uuden dstringin assosioituneen dynaamisen array-määritteen arvoihin.
  4. toLower, join ja chomp ovat merkkijonofunktioita, joita D sallii käyttää metodisyntaksin kanssa. Tällaisten funktioiden nimi on usein hyvin samankaltainen kuin Pythonin merkkijonometodien. ToLower muuntaa merkkijonon pieneksi, join(" ") yhdistää merkkijonojen joukon yhdeksi merkkijonoksi käyttäen erotinmerkkinä yhtä välilyöntiä, ja chomp poistaa merkkijonon lopusta rivinvaihdon, jos sellainen on olemassa.
  5. Sort on std.algorithm-funktio, joka lajittelee joukon paikallaan ja luo ainutlaatuisen allekirjoituksen sanoille, jotka ovat toistensa anagrammeja. Sort():n paluuarvon release()-metodi on kätevä, jotta koodi pysyy yhtenä lausekkeena.
  6. Toinen foreach iteroi assosiatiivisen matriisin arvoja, ja se pystyy päättelemään sanojen tyypin.
  7. avain annetaan muuttumattomalle muuttujalle, sen tyyppi päätellään.
  8. UTF-32 dchar[] käytetään normaalin UTF-8 char[]:n sijasta, muuten sort() kieltäytyy lajittelemasta sitä. On olemassa tehokkaampia tapoja kirjoittaa tämä ohjelma, jotka käyttävät vain UTF-8:aa.
 

Aiheeseen liittyvät artikkelit

Tekijä

AlegsaOnline.com D-ohjelmointikieli: C++-yhteensopiva, muistiturvallinen järjestelmäkieli

URL: https://fi.alegsaonline.com/art/24999

Jaa

Lähteet