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)[].
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.
signs2wordson sisäänrakennettu assosiatiivinen matriisi, joka yhdistää dstring-avaimet (32-bittiset / char-avaimet) dstring-matriiseihin. Se on samanlainen kuindefaultdict(list)Pythonissa.lines(Tiedosto())tuottaa rivit laiskasti, rivinvaihdon kanssa. Sen jälkeen se on kopioitavaidup-ominaisuudella, jottasaadaan merkkijono, jota käytetään assosiatiivisen array-joukon arvoina (arrayjen idup-ominaisuus palauttaa muuttumattoman duplikaatin arraysta, mikä on tarpeen, koska dstring-tyyppi on itse asiassaimmutable(dchar)[]). Sisäänrakennetut assosiatiiviset matriisit vaativat muuttumattomat avaimet.- Operaattori
~=liittää uuden dstringin assosioituneen dynaamisen array-määritteen arvoihin. toLower,joinjachompovat merkkijonofunktioita, joita D sallii käyttää metodisyntaksin kanssa. Tällaisten funktioiden nimi on usein hyvin samankaltainen kuin Pythonin merkkijonometodien.ToLowermuuntaa merkkijonon pieneksi,join(" ")yhdistää merkkijonojen joukon yhdeksi merkkijonoksi käyttäen erotinmerkkinä yhtä välilyöntiä, jachomppoistaa merkkijonon lopusta rivinvaihdon, jos sellainen on olemassa.Sorton std.algorithm-funktio, joka lajittelee joukon paikallaan ja luo ainutlaatuisen allekirjoituksen sanoille, jotka ovat toistensa anagrammeja.Sort():n paluuarvonrelease()-metodi on kätevä, jotta koodi pysyy yhtenä lausekkeena.- Toinen
foreachiteroi assosiatiivisen matriisin arvoja, ja se pystyy päättelemäänsanojentyypin. avainannetaan muuttumattomalle muuttujalle, sen tyyppi päätellään.- 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 Leandro Alegsa
URL: https://fi.alegsaonline.com/art/24999
Lähteet
- ddj.com : "The Case for D"
- ddili.org : "Programming in D"