Luettelotyyppi (lyhennetty luettelointi , eng. enumeration, enumerated type ) - ohjelmoinnin tietotyyppi , jonka arvojoukko on rajoitettu tunnisteluettelo.
Luettelotyyppi määritellään joukoksi tunnisteita, joilla on kielen näkökulmasta sama rooli kuin tavalliset nimetyt vakiot, mutta jotka liittyvät kyseiseen tyyppiin. Klassinen kuvaus Pascalin luettelotyypistä on seuraava:
tyyppi Cardsuit = ( mailat , timantit , sydämet , pata ) ;Tässä ilmoitetaan Cardsuit-tietotyyppi, jonka arvot voivat olla mikä tahansa neljästä luetellusta vakiosta. Tyyppimuuttuja Cardsuitvoi ottaa yhden arvoista clubs, diamonds, hearts, spades, se on sallittua vertailla laskentatyypin arvoja yhtäläisyydelle tai epätasa-arvolle sekä käyttää niitä valintalausekkeissa (Pascal - case) arvoina, jotka tunnistavat vaihtoehdot.
Luetteloiden käyttö mahdollistaa ohjelmien lähdekoodien luettavuuden, koska ne mahdollistavat tiettyjä arvoja koodaavien "maagisten numeroiden" korvaamisen luettavissa olevilla nimillä.
Joidenkin kielten luetteloiden perusteella voidaan luoda tyyppijoukkoja . Tällaisissa tapauksissa joukko ymmärretään (ja kuvataan) enum-tyyppisten ainutlaatuisten arvojen järjestämättömänä kokoelmana.
Luettelotyyppiä voidaan käyttää muuttujien ja funktioiden muodollisten parametrien (proseduurit, menetelmät) määrittelyssä. Luettelotyyppiset arvot voidaan määrittää vastaaville muuttujille ja kuljettaa niitä vastaavien tyyppien parametrien läpi funktioissa. Lisäksi tasa-arvon ja eriarvoisuuden lueteltujen arvojen vertailua tuetaan aina. Jotkut kielet tukevat myös muita vertailuoperaattoreita lueteltujen tyyppien arvoille. Kahden luetun arvon vertailun tulos tällaisissa tapauksissa määräytyy pääsääntöisesti näiden arvojen järjestyksen mukaan tyyppiselvityksessä - arvoa, joka esiintyy aikaisemmin tyyppiilmoituksessa, pidetään "pienempänä" kuin arvo, tapahtuu myöhemmin. Joskus taulukon indeksityyppinä voidaan käyttää myös lueteltua tyyppiä tai jotakin lueteltua tyyppiä olevaa arvoaluetta. Tässä tapauksessa taulukossa on yksi elementti jokaiselle valitun alueen arvolle, ja elementtien todellinen järjestys vastaa tyyppiilmoituksen arvojen järjestystä.
Normaalisti kokoamisen aikana luettelointiarvot esitetään kokonaislukuina. Tietystä ohjelmointikielestä riippuen tällainen esitys voi olla joko kokonaan piilotettu ohjelmoijalta tai hänen käytettävissään käyttämällä tiettyjä "kiertotapoja" (esimerkiksi enum-tyypin arvon pakotettu muuntaminen "kokonaisluku"-tyyppiseksi arvoksi) tai jopa ohjelmoijan ohjaama (tällaisissa tapauksissa ohjelmoijalla on mahdollisuus nimenomaisesti määrittää, millä numeroilla kaikki tai jotkin enum-tyypin arvot koodataan. Kaikilla vaihtoehdoilla on hyvät ja huonot puolensa. Toisaalta kyky käyttää laskentatyypin muodostavien vakioiden numeerisia arvoja, varsinkin kun sitä käytetään väärin, estää näiden tyyppien käytön ja aiheuttaa virhevaaran (käytettäessä numeerisia arvoja joita tyypissä ei ole vastaavia vakioita). Toisaalta eksplisiittinen arvonhallinta tarjoaa joitain lisäominaisuuksia. Se mahdollistaa esimerkiksi enum-tyyppien käytön järjestettäessä käyttöliittymää muilla kielillä kirjoitetuilla moduuleilla, jos ne käyttävät tai palauttavat kokonaislukukoodattuja arvoja jostain ennalta määritetystä joukosta.
Toinen mahdollisuus, jonka luetellut tyypit tarjoavat kielen toteutustasolla, on muistin säästäminen. Pienellä määrällä enum-tyyppiä muutama bitti riittää tallentamaan tämän tyyppisen arvon (edellä oleva tyyppi Cardsuitvaatii vain kaksi bittiä arvoa kohden, kun taas tavallinen kokonaisluku useimmissa käytetyissä arkkitehtuureissa vie 32 bittiä - 16 kertaa enemmän), ja kääntäjä voi käyttää tätä tosiasiaa tiivistämään tietojen tallentamista muistiin. Tämä voi olla erityisen tärkeää, jos yhteen tietueeseen on tallennettu useita enum-tyyppien arvoja - tietueiden tiivistäminen niitä suuria määriä käsiteltäessä voi vapauttaa paljon muistia. Kääntäjät eivät yleensä ota käyttöön tätä ominaisuutta, ainakaan viime aikoina, kun tietokoneen muisti on tullut paljon halvemmaksi.
Luettelotyyppi on perinteinen kehittyneille ohjelmointikielille, sitä käytetään melko laajalti ja sitä pidetään usein itsestäänselvyytenä. Tämä tyyppi ei kuitenkaan ole vailla kritiikkiä ohjelmoinnin teoreetikoilta ja harjoittajilta. Joten Oberon -ohjelmointikieltä kehitettäessä luetellut tyypit sisällytettiin kielestä poistettujen ominaisuuksien luetteloon. Kielen suunnittelija Niklaus Wirth mainitsi seuraavat syyt:
Toisaalta esimerkiksi Javassa , joka alun perin ei sisältänyt lueteltua tyyppiä, tämä tyyppi otettiin myöhemmin käyttöön paitsi mukavuussyistä myös luotettavuudesta: nimettyjen vakioryhmien käytön ongelmana numerointien sijaan on se, että kääntäjä ei voi hallita arvovakioiden yksilöllisyyttä, samoin kuin mahdollisuutta antaa satunnaisesti arvoja muuttujille, jotka eivät vastaa mitään näistä vakioista.
Ada-kielessä luettelot määritetään avainsanalla is, jota seuraa pilkuilla eroteltu arvoluettelo:
tyyppi Cardsuit on ( mailat , timantit , sydämet , pata );C :n alkuperäisellä K&R -murteella ei ollut lueteltuja tyyppejä, mutta ne lisättiin ANSI C -standardiin .
enum korttipuku { KLUBIT , Timantteja , SYDÄMET , PATA };Dynaamisissa, heikosti kirjoitetuissa kielissä, joissa on C-tyyppinen syntaksi (kuten perl tai JavaScript ), ei yleensä ole enumeita.
C++C++-luettelot perivät suoraan C-luetteloiden käyttäytymisen, paitsi että C++:n lueteltu tyyppi on todellinen tyyppi ja avainsanaa enumkäytetään vain sellaisen tyypin määrittämisessä. Jos listauksena olevaa parametria käsiteltäessä ei käsitellä mitään luettelon arvoa (esimerkiksi yksi luettelointielementeistä on unohdettu käsitellä konstruktiossa switch), kääntäjä voi antaa varoituksen unohdetusta arvosta. [2]
C++11 tarjoaa toisen, tyyppiturvallisen enum-tyypin, joka ei ole implisiittisesti muunnettavissa kiinteäksi tyypiksi. Tämä määritellään ilmauksella "enum class". Esimerkiksi:
enum class Väri { Punainen , Vihreä , Sininen };Perustyyppi on tietyn integraalityypin toteutus, joka on riittävän suuri sisältämään kaikki luetellut arvot (sen ei tarvitse olla pienin mahdollinen tyyppi!). C++:ssa voit määrittää perustyypin suoraan. Tämä mahdollistaa enumien "edellyttämisen":
enum class Väri : pitkä { Punainen , Vihreä , Sininen }; // on vastattava muistityypin "long" kokoa ja asettelua enum class Muodot : char ; // alustava ilmoitus. Jos myöhemmin määritetään arvoja, jotka eivät mahdu 'char' -kohtaan, tämä on virhe. C# enum Cardsuit { Clubs , Diamonds , Spades , Hearts } JavaAlkuperäisessä Javassa ei ollut enumeita, vaan sen sijaan ehdotettiin luokkien käyttöä staattisilla vakioilla. Koska versio 5 (1.5) luettelointi on otettu kieleen, ne ovat täysi luokka, johon voit lisätä mielivaltaisen määrän kenttiä ja menetelmiä. Enummit otettiin käyttöön tyyppiturvallisuuden parantamiseksi. [3]
enum Cardsuit { Clubs , Diamonds , Spades , Hearts } Kotlin enum class Suunta { POHJOIS , ETELÄ , LÄNSI , ITÄ }Joissakin ohjelmointikielissä (esim. Haskell) luetteloita voidaan emuloida käyttämällä algebrallisia tyyppejä . Esimerkiksi Boolen tyyppi, joka sisältää kaksi tunnistetta totuusarvojen esittämiseksi, on koodattu seuraavasti:
tiedot Bool = False | Totta
Tietotyypit | |
---|---|
Käsittämätön | |
Numeerinen | |
Teksti | |
Viite | |
Komposiitti | |
abstrakti | |
muu | |
liittyvät aiheet |