Uppräknad typ

Inom datorprogrammering är en uppräknad typ (även kallad enumeration , enum eller faktor i programmeringsspråket R och en kategorisk variabel i statistik ) en datatyp som består av en uppsättning namngivna värden som kallas element , medlemmar , enumeral eller enumeratorer av typen. Uppräkningsnamnen är vanligtvis identifierare som beter sig som konstanter i språket. En uppräknad typ kan ses som en degenererad märkt förening av enhetstyp . En variabel som har deklarerats ha en uppräknad typ kan tilldelas vilken som helst av uppräkningarna som ett värde. Med andra ord, en uppräknad typ har värden som skiljer sig från varandra, och som kan jämföras och tilldelas, men som inte anges av programmeraren som att ha någon särskild konkret representation i datorns minne; kompilatorer och tolkar kan representera dem godtyckligt.

Till exempel kan de fyra färgerna i en kortlek vara fyra uppräknare som heter Klubb , Diamant , Hjärta och Spader , som tillhör en uppräknad typ med namnet färg . Om en variabel V deklareras med färg som sin datatyp, kan man tilldela någon av dessa fyra värden till den.

Även om uppräkningarna vanligtvis är distinkta, kan vissa språk tillåta att samma uppräknare anges två gånger i typens deklaration. Namnen på uppräknare behöver inte vara semantiskt fullständiga eller kompatibla i någon mening. Till exempel kan en uppräknad typ som kallas färg definieras så att den består av uppräkningarna Röd , Grön , Zebra , Saknas och Bacon . På vissa språk definierar deklarationen av en uppräknad typ också avsiktligt en ordning på dess medlemmar; i andra är uppräkningarna oordnade; i andra fortfarande uppstår en implicit ordning från att kompilatorn konkret representerar uppräknare som heltal.

Vissa uppräkningstyper kan vara inbyggda i språket. Den booleska typen är till exempel ofta en fördefinierad uppräkning av värdena False och True . Många språk tillåter användare att definiera nya uppräknade typer.

Värden och variabler av en uppräknad typ implementeras vanligtvis med någon heltalstyp som underliggande representation. Vissa språk, särskilt systemprogrammeringsspråk , tillåter användaren att specificera bitkombinationen som ska användas för varje uppräkningsenhet, vilket kan vara användbart för att effektivt representera uppsättningar av uppräknare som bitsträngar med fast längd. I typteorin betraktas ofta uppräknade typer som taggade fackföreningar av enhetstyper . Eftersom sådana typer är av formen kan de också skrivas som naturliga tal.

Logisk grund

Vissa tidiga programmeringsspråk hade ursprungligen inte uppräknade typer. Om en programmerare ville att en variabel, till exempel myColor , skulle ha värdet rött, skulle variabeln rött deklareras och tilldelas något godtyckligt värde, vanligtvis en heltalskonstant. Variabeln röd skulle sedan tilldelas till myColor . Andra tekniker tilldelade godtyckliga värden till strängar som innehöll namnen på uppräkningarna.

Dessa godtyckliga värden kallades ibland magiska siffror eftersom det ofta inte fanns någon förklaring till hur siffrorna erhölls eller om deras faktiska värden var signifikanta. Dessa magiska siffror kan göra källkoden svårare för andra att förstå och underhålla.

Uppräknade typer gör å andra sidan koden mer självdokumenterande. Beroende på språket kan kompilatorn automatiskt tilldela standardvärden till uppräkningarna och därigenom dölja onödiga detaljer från programmeraren. Dessa värden kanske inte ens är synliga för programmeraren (se informationsgömma ) . Uppräknade typer kan också förhindra en programmerare från att skriva ologisk kod, som att utföra matematiska operationer på uppräkningarnas värden. Om värdet på en variabel som tilldelats en uppräkning skulle skrivas ut, kan vissa programmeringsspråk också skriva ut namnet på uppräknaren snarare än dess underliggande numeriska värde. En ytterligare fördel är att uppräknade typer kan tillåta kompilatorer att framtvinga semantisk korrekthet. Till exempel: myColor = TRIANGLE kan förbjudas, medan myColor = RED accepteras, även om TRIANGLE och RED båda internt representeras som 1 .

Begreppsmässigt liknar en uppräknad typ en lista med nominal (numeriska koder), eftersom varje möjligt värde av typen tilldelas ett distinkt naturligt tal. En given uppräknad typ är alltså en konkret implementering av denna föreställning. När ordning är meningsfull och/eller används för jämförelse, blir en uppräknad typ en ordningstyp .

Konventioner

Programmeringsspråk tenderar att ha sina egna, ofta flera, programmeringsstilar och namnkonventioner . Variabeln som tilldelas en uppräkning är vanligtvis ett substantiv i singularform och följer ofta antingen en PascalCase eller versaler , medan gemener och andra ses mer sällan.

Syntax i flera programmeringsspråk

Pascal och syntaktiskt liknande språk

Pascal

I Pascal kan en uppräknad typ implicit deklareras genom att lista värdena i en lista inom parentes:

  
         var  färg  :  (  klöver  ,  ruter  ,  hjärter  ,  spader  )  ; 

Deklarationen kommer ofta att visas i en typsynonymdeklaration, så att den kan användas för flera variabler:

  
         
      
              
                
           
  
            
      typ  cardsuit  =  (  klöver  ,  ruter  ,  hjärter  ,  spader  )  ;  kort  =  rekord  färg  :  kort färg  ;  värde  :  1  ..  13  ;  slut  ;  var  hand  :  array  [  1  ..  13  ]  av  kort  ;  trumf  :  cardsuit  ; 

Den ordning i vilken uppräkningsvärdena ges har betydelse. En uppräknad typ är en ordningstyp, och pred och succ kommer att ge föregående eller nästa värde för uppräkningen, och ord kan konvertera uppräkningsvärden till deras heltalsrepresentation. Standard Pascal erbjuder dock ingen konvertering från aritmetiska typer till uppräkningar. Extended Pascal erbjuder denna funktionalitet via en utökad succ- funktion. Vissa andra Pascal-dialekter tillåter det via typkastningar. Vissa moderna ättlingar till Pascal, som Modula-3 , tillhandahåller en speciell konverteringssyntax med en metod som kallas VAL ; Modula-3 behandlar också BOOLEAN och CHAR som speciella fördefinierade uppräknade typer och använder ORD och VAL för standard ASCII- avkodning och -kodning.

Språk i Pascal-stil tillåter också att uppräkning används som arrayindex:

  
         var  suitcount  :  array  [  cardsuit  ]  av  heltal  ; 

Ada

I Ada ersattes användningen av "=" med "är" vilket lämnar definitionen ganska lika:

       typ  Cardsuit  är  (  klöver  ,  ruter  ,  hjärter  ,  spader  ); 

Förutom Pred , Succ , Val och Pos Ada stöder även enkla strängkonverteringar via Image och Value .

I likhet med språk i C-stil tillåter Ada att den interna representationen av uppräkningen specificeras:

  
              för  Cardsuit-  användning  (  klöver  =>  1  ,  ruter  =>  2  ,  hjärter  =>  4  ,  spader  =>  8  ); 

Till skillnad från språk i C-stil tillåter Ada också att antalet bitar i uppräkningen specificeras:

      för  Cardsuit  '  Storlek  använd  4  ;  -- 4 bitar 

Dessutom kan man använda uppräkningar som index för matriser, som i Pascal, men det finns attribut definierade för uppräkningar

         
        
         
         
         
       Shuffle  :  konstant  array  (  Cardsuit  )  av  Cardsuit  :=  (  Clubs  =>  Cardsuit  '  Succ  (  Clubs  ),  -- se attribut för uppräkningar 'First, 'Last, 'Succ, 'Pred  Diamonds  =>  Hearts  ,  --an explicit value  Hearts  =>  Cardsuit  '  Sista  ,  --första uppräkningsvärdet av typen Cardsuit t.ex. klöver  Spader  =>  Cardsuit  '  Första  --sista uppräkningsvärdet av typen Cardsuit t.ex. spader  ); 

Liksom Modula-3 behandlar Ada Boolean och Character som speciella fördefinierade (i paketet " Standard ") uppräknade typer. Till skillnad från Modula-3 kan man också definiera egna karaktärstyper:

          typ  Kort  är  ('  7  ',  '  8  ',  '  9  ',  '  J  ',  '  Q  ',  '  K  ',  '  A  '); 

C och syntaktiskt liknande språk

C

Den ursprungliga K&R- dialekten för programmeringsspråket C hade inga uppräknade typer. I C skapas uppräkningar av explicita definitioner ( enum i sig orsakar inte allokering av lagring) som använder nyckelordet enum och påminner om struktur- och unionsdefinitioner :

  
    
    
    
    


  
      
      
 

   enum  cardsuit  {  Clubs  ,  Diamonds  ,  Hearts  ,  Spades  };  struct  card  {  enum  cardsuit  suit  ;  kort  int  värde  ;  }  hand  [  13  ];  enum  cardsuit  trumf  ; 

C exponerar heltalsrepresentationen av uppräkningsvärden direkt för programmeraren. Heltal och enumvärden kan blandas fritt, och alla aritmetiska operationer på enumvärden är tillåtna. Det är till och med möjligt för en enumvariabel att ha ett heltal som inte representerar något av uppräkningsvärdena. Faktum är att enligt språkdefinitionen kommer ovanstående kod att definiera klöver , ruter , hjärter och spader som konstanter av typen int , som endast kommer att konverteras (tyst) till enum cardsuit om de lagras i en variabel av den typen.

C tillåter också programmeraren att välja värdena för uppräkningskonstanter explicit, även utan typ. Till exempel,

  
         
      
        
        
 enum  cardsuit  {  Clubs  =  1  ,  Ruter  =  2  ,  Hjärter  =  4  ,  Spader  =  8  }; 

skulle kunna användas för att definiera en typ som tillåter matematiska uppsättningar av färger att representeras som en enum cardsuit genom bitvisa logiska operationer.

Sedan C23 kan den underliggande typen av en uppräkning specificeras av programmeraren:

    
         
      
        
        
 enum  cardsuit  :  char  {  Klöver  =  1  ,  Ruter  =  2  ,  Hjärter  =  4  ,  Spader  =  8  }; 

C#

Uppräknade typer i programmeringsspråket C# bevarar det mesta av "små heltals" semantiken i C:s uppräkningar. Vissa aritmetiska operationer är inte definierade för enums, men ett enumvärde kan explicit konverteras till ett heltal och tillbaka igen, och en enumvariabel kan ha värden som inte deklarerades av enumdefinitionen. Till exempel givet

 

    
    
    
    
 enum  Cardsuit  {  klöver  ,  ruter  ,  spader  ,  hjärter  } 

uttrycken CardSuit.Diamonds + 1 och CardSuit.Hearts - CardSuit.Clubs är tillåtna direkt (eftersom det kan vara vettigt att gå igenom värdeföljden eller fråga hur många steg det finns mellan två värden), men CardSuit.Hearts * CardSuit. Spader anses vara mindre vettigt och är bara tillåtet om värdena först konverteras till heltal.

C# tillhandahåller också den C-liknande funktionen för att kunna definiera specifika heltalsvärden för uppräkningar. Genom att göra detta är det möjligt att utföra binära operationer på uppräkningar, och därmed behandla uppräkningsvärden som uppsättningar av flaggor. Dessa flaggor kan testas med binära operationer eller med Enum-typens inbyggda 'HasFlag'-metod.

Uppräkningsdefinitionen definierar namn för de valda heltalsvärdena och är syntaktisk sugar , eftersom det är möjligt att tilldela en enumvariabel andra heltalsvärden som inte omfattas av enumdefinitionen.

C++

C++ har uppräkningstyper som är direkt ärvda från C och fungerar mestadels som dessa, förutom att en uppräkning är en riktig typ i C++, vilket ger extra kompileringstidskontroll. Dessutom (som med structs) kombineras nyckelordet C++ enum med en typedef , så att istället för att namnge typen enum name , helt enkelt ge det namn . Detta kan simuleras i C med en typedef: typedef enum { Value1 , Value2 } name ;

C++11 tillhandahåller också en andra typ av uppräkning, som kallas en scoped enumeration . Dessa är typsäkra: uppräkningarna konverteras inte implicit till en heltalstyp. Detta möjliggör bland annat att I/O-strömning kan definieras för uppräkningstypen. En annan egenskap med omfångade uppräkningar är att uppräkningarna inte läcker, så användning kräver prefix med namnet på uppräkningen (t.ex. Färg::Röd för den första uppräkningen i exemplet nedan), såvida inte en uppräkningsdeklaration (infört i C+ ) +20 ) har använts för att bringa uppräkningarna in i det aktuella omfånget. En omfångad uppräkning specificeras av frasen enum class (eller enum struct ). Till exempel:

      enum  klass  Färg  {  Röd  ,  Grön  ,  Blå  }; 

Den underliggande typen av en uppräkning är en implementeringsdefinierad integraltyp som är tillräckligt stor för att hålla alla uppräknade värden; det behöver inte vara den minsta möjliga typen. Den underliggande typen kan specificeras direkt, vilket tillåter "forward deklarationer" av uppräkningar:

         
       enum  klass  Färg  :  lång  {  Röd  ,  Grön  ,  Blå  };  // måste passa i storlek och minneslayout typen 'lång'  enum  -klass  Former  :  char  ;  // vidarebefordran deklaration. Om det senare finns definierade värden som inte passar i "char" är det ett fel.  

Go använder nyckelordet iota för att skapa uppräknade konstanter.

  

 
                 
           
    
    
 typ  ByteSize  float64  const  (  _  =  iota  // ignorera det första värdet genom att tilldela den tomma identifieraren  KB  ByteSize  =  1  <<  (  10  *  iota  )  MB  GB  ) 

Java

J2SE version 5.0 av programmeringsspråket Java lade till uppräknade typer vars deklarationssyntax liknar den för C :

       

  enum  Cardsuit  {  KLUBBAR  ,  DIAMANTER  ,  SPADER  ,  HJÄRTOR  };  ...  Cardsuit  trumf  ; 

Java-typsystemet behandlar dock uppräkningar som en typ skild från heltal, och sammanblandning av enum- och heltalsvärden är inte tillåten. Faktum är att en enum-typ i Java faktiskt är en speciell kompilatorgenererad klass snarare än en aritmetisk typ, och enum-värden beter sig som globala förgenererade instanser av den klassen. Enumtyper kan ha instansmetoder och en konstruktor (vars argument kan specificeras separat för varje enumvärde). Alla enumtyper utökar implicit den abstrakta klassen Enum . En uppräkningstyp kan inte instansieras direkt.

Internt innehåller varje enumvärde ett heltal, motsvarande den ordning som de deklareras i källkoden, med start från 0. Programmeraren kan inte ställa in ett anpassat heltal för ett enumvärde direkt, men man kan definiera överbelastade konstruktorer som sedan kan tilldela godtyckliga värden till självdefinierade medlemmar av enum-klassen. Att definiera getters ger sedan åtkomst till dessa självdefinierade medlemmar. Det interna heltal kan erhållas från ett enum-värde med ordinal() och listan med enum-värden för en uppräkningstyp kan erhållas i ordning med hjälp av values()- metoden. Det är i allmänhet avrådigt för programmerare att konvertera uppräkningar till heltal och vice versa. Uppräknade typer är jämförbara med det interna heltal; som ett resultat kan de sorteras.

Java-standardbiblioteket tillhandahåller verktygsklasser att använda med uppräkningar. Klassen EnumSet implementerar en uppsättning enumvärden; den är implementerad som en bitarray , vilket gör den mycket kompakt och lika effektiv som explicit bitmanipulation, men säkrare. Klassen EnumMap implementerar en karta över enumvärden till objekt. Det är implementerat som en array, med heltalsvärdet för enumvärdet som index.

Perl

Dynamiskt typade språk i den syntaktiska traditionen av C (t.ex. Perl eller JavaScript ) tillhandahåller i allmänhet inte uppräkningar. Men i Perl-programmering kan samma resultat erhållas med stränglistan för stenografi och hash ( eventuellt skivor ) :

   
   
            
     
             
           my  @enum  =  qw(Clubs Diamonds Hearts Spades)  ;  min  (  %set1  ,  %set2  );  @set1  {  @enum  }  =  ();  # all cleared  @set2  {  @enum  }  =  (  1  )  x  @enum  ;  # alla inställda på 1  $set1  {  Clubs  }  ...  # false  $set2  {  Diamonds  }  ...  # true 

Raku

Raku (tidigare känd som Perl 6) stöder uppräkningar. Det finns flera sätt att deklarera uppräkningar i Raku, alla skapar en back-end-karta.

   enum  Katt  <sphynx siames bengal korthår annat>  ;  # Använda "citat-ord" 
  enum  Cat  (  'sphynx'  ,  'siames'  ,  'bengal'  ,  'shorthair'  ,  'annan'  );  # Använda en lista 
 0 enum  Cat  (  sphynx  =>  ,  siames  =>  1  ,  bengal  =>  2  ,  korthår  =>  3  ,  annan  =>  4  );  # Använda parkonstruktörer 
 0 enum  Cat  (:  sphynx  (  ), :  siames  (  1  ), :  bengal  (  2  ),  korthårig  (  3  ), :  annan  (  4  ));  # Ett annat sätt att använda par, du kan också använda `:0sphynx` 

PHP

Enums lades till i PHP version 8.1.

 

     
     
     
     
 enum  CardSuit  {  case  Hearts  ;  hölje  Diamanter  ;  fall  Klubbar  ;  fall  Spader  ;  } 

Rost

Även om Rust använder nyckelordet enum som C, använder det det för att beskriva taggade fackföreningar , vilka enums kan betraktas som en degenererad form av. Rusts enums är därför mycket mer flexibla och kan innehålla struktur- och tupelvarianter.

  
    
         
     
       
 enum  Message  {  Quit  ,  Move  {  x  :  i32  ,  y  :  i32  },  // struct  Write  (  String  ),  // single-element tuple  ChangeColor  (  i32  ,  i32  ,  i32  ),  // three-element tuple  } 

Snabb

I C tilldelar uppräkningar relaterade namn till en uppsättning heltalsvärden. I Swift är uppräkningar mycket mer flexibla och behöver inte ge ett värde för varje fall av uppräkningen. Om ett värde (kallat ett råvärde ) tillhandahålls för varje uppräkningsfall, kan värdet vara en sträng, ett tecken eller ett värde av valfri heltals- eller flyttalstyp.

Alternativt kan uppräkningsfall specificera associerade värden av vilken typ som helst som ska lagras tillsammans med varje olika fallvärde, ungefär som fackföreningar eller varianter gör på andra språk. Man kan definiera en gemensam uppsättning relaterade fall som en del av en uppräkning, som var och en har olika värden av lämpliga typer associerade med sig.

I Swift är uppräkningar en förstklassig typ. De använder många funktioner som traditionellt bara stöds av klasser, såsom beräknade egenskaper för att ge ytterligare information om uppräkningens aktuella värde, och instansmetoder för att tillhandahålla funktionalitet relaterad till de värden som uppräkningen representerar. Uppräkningar kan också definiera initialiserare för att ge ett initialt fallvärde och kan utökas för att utöka deras funktionalitet utöver deras ursprungliga implementering; och kan följa protokoll för att tillhandahålla standardfunktionalitet.

  
     
     
     
     
 enum  CardSuit  {  fodral  klubbor  fodral  diamanter  fodral  hjärtan  fodral  spader  } 

Till skillnad från C och Objective-C tilldelas Swift-uppräkningsfall inte ett standardvärde för heltal när de skapas. I CardSuit-exemplet ovan är klöver, ruter, hjärter och spader inte implicit lika med 0, 1, 2 och 3. Istället är de olika uppräkningsfallen fullvärdiga värden i sin egen rätt, med en explicit definierad typ av CardSuit .

Flera skiftlägen kan visas på en enda rad, separerade med kommatecken:

  
        
 enum  CardSuit  {  case  klubbor  ,  ruter  ,  hjärtan  ,  spader  } 

När man arbetar med uppräkningar som lagrar heltals- eller strängråvärden, behöver man inte explicit tilldela ett råvärde för varje fall eftersom Swift automatiskt tilldelar värdena.

Till exempel, när heltal används för råvärden, är det implicita värdet för varje fall ett mer än det föregående fallet. Om det första fallet inte har något värde är dess värde 0.

Uppräkningen nedan är en förfining av den tidigare planetuppräkningen, med heltalsråvärden för att representera varje planets ordning från solen:

   
              
 enum  Planet  :  Int  {  case  kvicksilver  =  1  ,  venus  ,  jorden  ,  mars  ,  jupiter  ,  saturnus  ,  uranus  ,  neptunus  } 

I exemplet ovan har Planet.mercury ett explicit råvärde på 1, Planet.venus har ett implicit råvärde på 2, och så vidare.

"Detaljer finns i Swift-dokumentationen online här."

TypeScript

TypeScript lägger till en "enum"-datatyp till JavaScript.

     
     enum  Cardsuit  {  Klöver  ,  Ruter  ,  Hjärter  ,  Spader  };  var  c  :  Cardsuit  =  Cardsuit  .  Diamanter  ; 

Som standard räknar antalet medlemmar upp från 0; detta kan åsidosättas genom att ställa in värdet på den första:

       
     enum  Cardsuit  {  Clubs  =  1  ,  Ruter  ,  Hjärter  ,  Spader  };  var  c  :  Cardsuit  =  Cardsuit  .  Diamanter  ; 

Alla värden kan ställas in:

             
     enum  Cardsuit  {  Clubs  =  1  ,  Ruter  =  2  ,  Hjärter  =  4  ,  Spader  =  8  };  var  c  :  Cardsuit  =  Cardsuit  .  Diamanter  ; 

TypeScript stöder mappning av det numeriska värdet till dess namn. Detta hittar till exempel namnet på värdet 2:

       
    

 enum  Cardsuit  {  Clubs  =  1  ,  Ruter  ,  Hjärter  ,  Spader  };  var  suitName  :  string  =  Cardsuit  [  2  ];  alert  (  suitName  ); 

Pytonorm

En enum -modul lades till i Python-standardbiblioteket i version 3.4.

   
 
      
      
      
       från  enum  import  Enum  class  Cards  (  Enum  ):  KLUBBAR  =  1  DIAMANTER  =  2  HJÄRTOR  =  3  SPADER  =  4 

Det finns också ett funktionellt API för att skapa uppräkningar med automatiskt genererade index (som börjar med ett):

    Kort  =  Enum  (  "Kort"  ,  "KLUBBAR DIAMANTER HJÄRTA SPADES"  ) 

Python-uppräkningar framtvingar inte semantisk korrekthet (en meningslös jämförelse med en inkompatibel uppräkning returnerar alltid False istället för att höja en TypeError ):

   
      
 
	   


 >>>  Färg  =  Enum  (  "Färg"  ,  "RÖD GRÖN BLÅ"  )  >>>  Form  =  Enum  (  "Shape"  ,  [  "CIRKEL"  ,  "TRIANGEL"  ,  "FYRKANTIG"  ,  "HEXAGON"  ])  >>>  def  has_vertices  (  form  ):  ...  returnera  form  !=  Form  .  CIRKLA  ...  >>>  has_vertices  (  Färg  .  GRÖN  )  Sant 

Fortran

Fortran har endast uppräknade typer för interoperabilitet med C; därför liknar semantiken C och, som i C, är enumvärdena bara heltal och ingen ytterligare typkontroll görs. C-exemplet från ovan kan skrivas i Fortran som

   
               
 enum  ,  bind  (  C  )  enumerator  ::  KLUBBER  =  1  ,  DIAMANTER  =  2  ,  HJÄRTA  =  4  ,  SPADER  =  8  slutuppräkning 

Visual Basic/VBA

Uppräknade datatyper i Visual Basic (upp till version 6) och VBA tilldelas automatiskt datatypen " Lång " och blir även själva en datatyp:


 
    
    
    
    
 

 
       
      
     
  'Nollbaserad  Enum  CardSuit  Klöver  Ruter  Hjärter  Spader  End  Enum  Sub  EnumExample  ()  Dim  färg  As  CardSuit  färg  =  Ruter  MsgBox  färg  End  Sub 

Exempelkod i VB.NET

 
    
    
    
    
 

 
       
      
    
  Enum  CardSuit  Klöver  Ruter  Hjärter  Spader  End  Enum  Sub  EnumExample  ()  Dim  färg  As  CardSuit  färg  =  CardSuit  .  Diamonds  MessageBox  .  visa  (  färg  )  End  Sub 

Läspa

Common Lisp använder specifikationen för medlemstyp, t.ex.

  
    (  deftype  cardsuit  (  )  '  (  medlemsklubb  diamant  hjärtspad  )  )    

som anger att objektet är av typen cardsuit om det är #'eql till klubba, ruter, hjärta eller spader. Medlemstypsspecifikatorn är dock inte giltig som en CLOS-parameterspecialist ( Common Lisp Object System) . Istället kan (eql atom) , som är ekvivalenten med (medlemsatom) användas (det vill säga att endast en medlem av uppsättningen kan anges med en eql-typspecifikator, men den kan användas som en CLOS-parameterspecialisering. ) Med andra ord, för att definiera metoder för att täcka en uppräknad typ, måste en metod definieras för varje specifikt element av den typen.

Dessutom,

   
     (  deftype  finite-element-set-type  (  &rest  elements  )  `  (  member  ,@  elements  )) 

kan användas för att definiera godtyckliga uppräknade typer vid körning. Till exempel

     (  finite-element-set-typ  club  diamond  heart  spade  ) 

skulle hänvisa till en typ som motsvarar den tidigare definitionen av cardsuit, som naturligtvis helt enkelt skulle ha använt

     (  medlemsklubbens  diamant  hjärtspade  )  _  _ 

men kan vara mindre förvirrande med funktionen #'medlem av stilistiska skäl.

Pil

Dart har stöd för den mest grundläggande formen av enums och har en syntax som är mycket lik andra språk som stöder enums.

  
  
  
  


  
     

  
      
      
    
    

      
      
    
    

      
      
    
    

      
      
    
    

     
      
    
    
  
   enum  CardSuite  { 
 Klöver  ,  Ruter  ,  Hjärter  ,  Spader  }  void  main  ()  {  CardSuite  card  =  CardSuite  .  Klubbar  ;  // Dart använder "switch"-operatorn för att matcha värdet på en enum med önskad utdata.      switch  (  kort  )  { 
 case  CardSuite  .  Klubbar:  {  print  (  "Klubbar"  );  }  bryta  ;  fodral  CardSuite  .  Diamanter:  {  print  (  "Diamanter"  );  }  bryta  ;  fodral  CardSuite  .  Hjärtan:  {  print  (  "Hjärtan"  );  }  bryta  ;  fodral  CardSuite  .  Spader:  {  print  (  "Spader"  );  }  bryta  ;  default  :  {  print  (  "Okänd"  );  }  bryta  ;  }  } 

Observera att växeloperatören inte garanterar att ärendena är fullständiga. Detta innebär att om du utelämnar ett fall kommer kompilatorn inte att skapa ett fel.

Algebraisk datatyp i funktionell programmering

I funktionella programmeringsspråk i ML -linjen (t.ex. Standard ML (SML), OCaml och Haskell ), kan en algebraisk datatyp med endast nullära konstruktorer användas för att implementera en uppräknad typ. Till exempel (i syntaxen för SML-signaturer):

         
        
     datatype  cardsuit  =  Klubbar  |  Diamanter  |  Hjärtan  |  Spader  typ  kort  =  {  färg  :  kort färg  ;  värde  :  int  }  val  hand  :  kortlista  val  trumf  :  kortfärg  _ 
   

I dessa språk är representationen av små heltal helt dold för programmeraren, om en sådan representation verkligen används av implementeringen. Haskell har dock typklassen Enum som en typ kan härleda eller implementera för att få en mappning mellan typen och Int .

Databaser

Vissa databaser stöder uppräknade typer direkt. MySQL tillhandahåller en uppräknad typ ENUM med tillåtna värden specificerade som strängar när en tabell skapas. Värdena lagras som numeriska index med den tomma strängen lagrad som 0, det första strängvärdet lagrat som 1, det andra strängvärdet lagrat som 2, etc. Värden kan lagras och hämtas som numeriska index eller strängvärden.

Exempel:

   
     
         
 CREATE  TABLE  -skjortor  (  namn  VARCHAR  (  40  ),  storlek  ENUM  (  'x-small'  ,  '  small'  ,  'medium'  ,  'large'  ,  'x-large' ) )  ; 

XML-schema

XML Schema stöder uppräknade typer genom uppräkningsaspekten som används för att begränsa de flesta primitiva datatyper som strängar.

 
  
     
       
       
       
       
    
  
 <xs:element  name=  "cardsuit"  >  <xs:simpleType>  <xs:restriction  base=  "xs:string"  >  <xs:enumeration  value=  "Clubs"  />  <xs:enumeration  value=  "Diamonds"  />  < xs:enumeration  value=  "Hjärter"  />  <xs:enumeration  value=  "Spader"  />  </xs:restriction>  </xs:simpleType>  </xs:element> 

Se även

externa länkar