3 > **<sup>Syntax</sup>**\
7 > [_GenericParams_]<sup>?</sup>
8 > [_WhereClause_]<sup>?</sup>
9 > `{` _EnumItems_<sup>?</sup> `}`
12 > _EnumItem_ ( `,` _EnumItem_ )<sup>\*</sup> `,`<sup>?</sup>
15 > _OuterAttribute_<sup>\*</sup> [_Visibility_]<sup>?</sup>\
16 > [IDENTIFIER] ( _EnumItemTuple_ | _EnumItemStruct_
17 > | _EnumItemDiscriminant_ )<sup>?</sup>
20 > `(` [_TupleFields_]<sup>?</sup> `)`
23 > `{` [_StructFields_]<sup>?</sup> `}`
25 > _EnumItemDiscriminant_ :\
26 > `=` [_Expression_]
28 An *enumeration*, also referred to as an *enum*, is a simultaneous definition of a
29 nominal [enumerated type] as well as a set of *constructors*, that can be used
30 to create or pattern-match values of the corresponding enumerated type.
32 Enumerations are declared with the keyword `enum`.
34 An example of an `enum` item and its use:
42 let mut a: Animal = Animal::Dog;
46 Enum constructors can have either named or unnamed fields:
51 Cat { name: String, weight: f64 },
54 let mut a: Animal = Animal::Dog("Cocoa".to_string(), 37.2);
55 a = Animal::Cat { name: "Spotty".to_string(), weight: 2.7 };
58 In this example, `Cat` is a _struct-like enum variant_, whereas `Dog` is simply
59 called an enum variant. Each enum instance has a _discriminant_ which is an
60 integer associated to it that is used to determine which variant it holds. An
61 opaque reference to this discriminant can be obtained with the
62 [`mem::discriminant`] function.
64 ## Custom Discriminant Values for Fieldless Enumerations
66 If there is no data attached to *any* of the variants of an enumeration,
67 then the discriminant can be directly chosen and accessed.
69 These enumerations can be cast to integer types with the `as` operator by a
70 [numeric cast]. The enumeration can optionally specify which integer each
71 discriminant gets by following the variant name with `=` followed by a [constant
72 expression]. If the first variant in the declaration is unspecified, then it is
73 set to zero. For every other unspecified discriminant, it is set to one higher
74 than the previous variant in the declaration.
83 let baz_discriminant = Foo::Baz as u32;
84 assert_eq!(baz_discriminant, 123);
87 Under the [default representation], the specified discriminant is interpreted as
88 an `isize` value although the compiler is allowed to use a smaller type in the
89 actual memory layout. The size and thus acceptable values can be changed by
90 using a [primitive representation] or the [`C` representation].
92 It is an error when two variants share the same discriminant.
95 enum SharedDiscriminantError {
100 enum SharedDiscriminantError2 {
103 OneToo = 1 // 1 (collision with previous!)
107 It is also an error to have an unspecified discriminant where the previous
108 discriminant is the maximum value for the size of the discriminant.
112 enum OverflowingDiscriminantError {
114 MaxPlusOne // Would be 256, but that overflows the enum.
118 enum OverflowingDiscriminantError2 {
119 MaxMinusOne = 254, // 254
121 MaxPlusOne // Would be 256, but that overflows the enum.
125 ## Zero-variant Enums
127 Enums with zero variants are known as *zero-variant enums*. As they have
128 no valid values, they cannot be instantiated.
134 Zero-variant enums are equivalent to the [never type], but they cannot be
135 coerced into other types.
138 # enum ZeroVariants {}
139 let x: ZeroVariants = panic!();
140 let y: u32 = x; // mismatched type error
143 ## Variant visibility
145 Enum variants syntactically allow a [_Visibility_] annotation, but this is
146 rejected when the enum is validated. This allows items to be parsed with a
147 unified syntax across different contexts where they are used.
150 macro_rules! mac_variant {
151 ($vis:vis $name:ident) => {
157 $vis Struct { f: u8 },
162 // Empty `vis` is allowed.
165 // This is allowed, since it is removed before being validated.
170 pub(super) T { f: String }
174 [IDENTIFIER]: ../identifiers.md
175 [_GenericParams_]: generics.md
176 [_WhereClause_]: generics.md#where-clauses
177 [_Expression_]: ../expressions.md
178 [_TupleFields_]: structs.md
179 [_StructFields_]: structs.md
180 [_Visibility_]: ../visibility-and-privacy.md
181 [enumerated type]: ../types/enum.md
182 [`mem::discriminant`]: ../../std/mem/fn.discriminant.html
183 [never type]: ../types/never.md
184 [numeric cast]: ../expressions/operator-expr.md#semantics
185 [constant expression]: ../const_eval.md#constant-expressions
186 [default representation]: ../type-layout.md#the-default-representation
187 [primitive representation]: ../type-layout.md#primitive-representations
188 [`C` representation]: ../type-layout.md#the-c-representation