Enumerated type
From Wikipedia, the free encyclopedia
The introduction to this article provides insufficient context for those unfamiliar with the subject. Please help improve the article with a good introductory style. |
In computer programming, an enumerated type is an abstract data type used to model an attribute that has a specific number of options (or identifiers) such as the suit of a playing card (i.e. a Club, Diamond, Heart or Spade). Using this type allows the program to handle the attribute more efficiently than a string while maintaining the readability of the source code.
At run-time, enumerated types are often implemented using integers (each identifier has a distinct integer value). However, compared to using just integers, enumerated types make program source more self-documenting than the use of explicit magic numbers. Depending on the language, the integer representation may not be visible to the programmer; this prevents the programmer from doing absurd things, like performing arithmetic on enumeration values.
In some languages, the boolean type of truth values is considered a predeclared enumerated type of two values.
Contents |
[edit] Pascal and syntactically similar languages
In Pascal, an enumerated type can be implicitly declared by listing the values in a parenthesised list:
var suit: (clubs, diamonds, hearts, spades);
The declaration will often appear in a type synonym declaration, such that it can be used for multiple variables:
type cardsuit = (clubs, diamonds, hearts, spades); card = record suit: cardsuit; value: 1 .. 13; end; var hand: array [ 1 .. 13 ] of card; trump: cardsuit;
The order in which the enumeration values are given matters. An enumerated type is an ordinal type, and the pred
and succ
functions will give the prior or next value of the enumeration, and ord
can convert enumeration values to their integer representation. Standard Pascal does not offer a conversion from arithmetic types to enumerations, however. Extended Pascal offers this functionality via an extended succ
function. Some other Pascal dialects allow it via type-casts. Some modern descendants of Pascal, such as Modula-3, provide a special conversion syntax using a method called VAL
; Modula-3 also treats BOOLEAN
and CHAR
as special pre-defined enumerated types and uses ORD
and VAL
for standard ASCII decoding and encoding.
Pascal style languages also allow for enumeration to be used as array index
var suitcount: array [cardsuit] of integer;
[edit] Ada
In Ada the use of "=" was replaced with "is" leaving the definition quite similar:
type Cardsuit is (clubs, diamonds, hearts, spades);
In addition to Pred, Succ, Val and Pos Ada also supports simple string conversions via Image and Value.
Similar to C-style languages Ada allows the internal representation of the enumeration to be specified:
for Cardsuit use (clubs => 1, diamonds => 2, hearts => 4, spades => 8);
Unlike C-style languages Ada also allows the size of the enumeration to be specified:
for Cardsuit'Size use 8;
Like Modula-3 Ada treats Boolean and Character as special pre-defined (in package "Standard") enumerated types. Unlike Modula 3 one can also define own character types:
type Cards is ("7", "8", "9", "J", "Q", "K", "A");
[edit] C and syntactically similar languages
The original K&R dialect of the C programming language did not have enumerated types, but they were added in the ANSI standard for C, which became C89. In C, enumerations are created by explicit definitions, which use the enum
keyword and are reminiscent of struct and union definitions:
enum cardsuit { CLUBS, DIAMONDS, HEARTS, SPADES }; struct card { enum cardsuit suit; short int value; } hand[13]; enum cardsuit trump;
C exposes the integer representation of enumeration values directly to the programmer. Integers and enum values can be mixed freely, and all arithmetic operations on enum values are permitted. It is even possible for an enum variable to hold an integer that does not represent any of the enumeration values. In fact, according to the language definition, the above code will define CLUBS
, DIAMONDS
, HEARTS
, and SPADES
as constants of type int, which will only be converted (silently) to enum cardsuit
if and when they are stored in a variable of that type.
C also allows the programmer to choose the values of the enumeration constants explicitly, even without type. For example,
enum { CLUBS = 1, DIAMONDS = 2, HEARTS = 4, SPADES = 8 };
could be used to define a type that allows mathematical sets of suits to be represented as an enum cardsuit
by bitwise logic operations.
Typeless languages in the syntactic tradition of C (e.g. perl or JavaScript) do not in general provide enumerations.
[edit] C++
C++ has enumeration types that are directly inherited from C's and work mostly like these, except that an enumeration is a real type in C++, so the "enum" keyword is only used when declaring the enumeration, but the name of the enumeration properly refers to the type thereafter.
[edit] Java
The J2SE version 5.0 of the Java programming language added enumerated types whose declaration syntax is similar to that of C's:
enum Cardsuit { Clubs, Diamonds, Spades, Hearts } ... Cardsuit trump ;
The Java type system, however, treats enumerations as a type separate from integers, and intermixing of enum and integer values is not allowed. In fact, an enum type in Java is actually a special compiler-generated class rather than an arithmetic type, and enum values behave as global pre-generated instances of that class. Enum types can have instance methods and a constructor (the arguments of which can be specified separately for each enum value). All enum types implicitly extend the Enum
abstract class. An enum type cannot be instantiated directly.
Internally, each enum value contains an integer, usually corresponding to the order in which they are declared in the source code, starting from 0. The programmer cannot set a custom integer for an enum value. This internal integer can be obtained from an enum value using the ordinal()
method, and you can get the list of enum values of an enumeration type in order using the values() method. It is generally discouraged for programmers to convert enums to integers and vice versa. Enumerated types are Comparable, using the internal integer; as a result, they can be sorted.
The Java standard library provides some utility data structures to use with enumerations. The EnumSet
class implements a Set of enum values; it is implemented as a bit array, so is very compact and efficient, but is safer to use than explicit bit field manipulations. The EnumMap
class implements a Map of enum values to other things; it is implemented as an array, with the integer value of the enum value serving as the index, so is very fast.
[edit] C#
Enumerated types in the C# programming language preserve most of the "small integer" semantics of C's enums. Some arithmetic operations are not defined for enums, but an enum value can be explicitly converted to an integer and back again, and an enum variable can have values that were not declared by the enum definition. For example, given
enum Cardsuit { Clubs, Diamonds, Spades, Hearts };
the expressions Diamonds + 1
and Hearts - Clubs
are allowed directly (because it makes sense to step through the sequence of values or ask how many steps there are between two values), but Hearts * Spades
is deemed to make less sense and is only allowed if the values are first converted to integers.
[edit] Visual Basic/VBA
Enumerated datatypes in Visual Basic and VBA are automatically assigned the "Long Integer" datatype and also become a datatype themselves:
Enum CardSuit Clubs Diamonds Hearts Spades End Enum Sub EnumExample() Dim suit As CardSuit suit = Diamonds MsgBox suit End Sub
[edit] Algebraic data type in functional programming
In functional programming languages in the ML lineage (e.g., SML, OCaml and Haskell), an algebraic data type with only nullary constructors can be used to implement an enumerated type. For example (in the syntax of SML signatures):
datatype cardsuit = Clubs | Diamonds | Hearts | Spades type card = { suit: cardsuit; value: int } val hand : card list val trump : cardsuit
In these languages the small-integer representation is completely hidden from the programmer, if indeed such a representation is employed by the implementation. However, Haskell has the Enum type class which a type can derive or implement to get a mapping between the type and Int.
[edit] Lisp
Common Lisp uses the member type specifier, e.g.
(deftype cardsuit () '(member club diamond heart spade))
which states that object is of type cardsuit if it is #'eql to club, diamond, heart or spade. The member type specifier is not valid as a CLOS parameter specializer, however. Instead, (eql atom), which is the equivalent to (member atom) may be used (that is, only one member of the set may be specified with an eql type specifier, however, it may be used as a CLOS parameter specializer.) In other words, in order to define methods to cover an enumerated type, a method must defined for each specific element of that type.
Additionally,
(deftype finite-element-set-type (&rest elements) `(member ,@elements))
may be used to define arbitrary enumerated types at runtime. For instance
(finite-element-set-type club diamond heart spade)
would refer to a type equivalent to the prior definition of cardsuit, as of course would simply have been using
(member club diamond heart spade)
but may be less confusing with the function #'member for stylistic reasons.
[edit] Databases
Some databases support enumerated types directly. MySQL provides an enumerated type ENUM with allowable values specified as strings when a table is created. The values are stored as numeric indices with the empty string stored as 0, the first string value stored as 1, the second string value stored as 2, etc. Values can be stored and retrieved as numeric indexes or string values.