Enumerations
Syntax
Enumeration :
enum
IDENTIFIER GenericParams? WhereClause?{
EnumItems?}
EnumItems :
EnumItem (,
EnumItem )*,
?EnumItem :
OuterAttribute* Visibility?
IDENTIFIER ( EnumItemTuple | EnumItemStruct )? EnumItemDiscriminant?EnumItemTuple :
(
TupleFields?)
EnumItemStruct :
{
StructFields?}
EnumItemDiscriminant :
=
Expression
An enumeration, also referred to as an enum, is a simultaneous definition of a nominal enumerated type as well as a set of constructors, that can be used to create or pattern-match values of the corresponding enumerated type.
Enumerations are declared with the keyword enum
.
An example of an enum
item and its use:
Enum constructors can have either named or unnamed fields:
In this example, Cat
is a struct-like enum variant, whereas Dog
is simply
called an enum variant.
An enum where no constructors contain fields are called a field-less enum. For example, this is a fieldless enum:
If a field-less enum only contains unit variants, the enum is called an unit-only enum. For example:
Discriminants
Each enum instance has a discriminant: an integer logically associated to it that is used to determine which variant it holds.
Under the default representation, the discriminant is interpreted as
an isize
value. However, the compiler is allowed to use a smaller type (or
another means of distinguishing variants) in its actual memory layout.
Assigning discriminant values
Explicit discriminants
In two circumstances, the discriminant of a variant may be explicitly set by
following the variant name with =
and a constant expression:
-
if the enumeration is "unit-only".
-
if a primitive representation is used. For example:
Implicit discriminants
If a discriminant for a variant is not specified, then it is set to one higher than the discriminant of the previous variant in the declaration. If the discriminant of the first variant in the declaration is unspecified, then it is set to zero.
Restrictions
It is an error when two variants share the same discriminant.
It is also an error to have an unspecified discriminant where the previous discriminant is the maximum value for the size of the discriminant.
Accessing discriminant
Via mem::discriminant
mem::discriminant
returns an opaque reference to the discriminant of
an enum value which can be compared. This cannot be used to get the value
of the discriminant.
Casting
If an enumeration is unit-only (with no tuple and struct variants), then its discriminant can be directly accessed with a numeric cast; e.g.:
Field-less enums can be casted if they do not have explicit discriminants, or where only unit variants are explicit.
Pointer casting
If the enumeration specifies a primitive representation, then the discriminant may be reliably accessed via unsafe pointer casting:
Zero-variant enums
Enums with zero variants are known as zero-variant enums. As they have no valid values, they cannot be instantiated.
Zero-variant enums are equivalent to the never type, but they cannot be coerced into other types.
Variant visibility
Enum variants syntactically allow a Visibility annotation, but this is rejected when the enum is validated. This allows items to be parsed with a unified syntax across different contexts where they are used.