Enum

An enum (from "enumeration") is a type that can be in one of several possible states, which are called variants. If it has exactly one variant, it is semantically similar to a struct. If it has no variants, it is semantically similar to the never type.

Enums are called sum types or tagged unions in some other languages. Although languages such as C, C# or Java have enums as well, Rust's enums are much more powerful.

Example
This is an enum with three variants,,   and. To allow converting an enum to a number, its representation can be set to an integer type. Furthermore, the value for each variant can be specified:

Like structs, enum variants can contain values. For example, this is how the type is defined:

An  is either   and contains a value, or it is. Note that fields of enum variants are always public.

Using enums
Variants of enums are specified with the scope operator. They can also be imported:

To test if an enum value is a certain variant, we need pattern matching:

Layout optimizations
Because Rust doesn't have a  pointer, values that might not be present must be wrapped in an. In many cases, this does not introduce any memory overhead, because Rust cleverly optimizes its layout.

For example, the  type from above only has 3 possible values, and   has 4. The compiler recognizes this, so it fits an  in a single byte. The same is true for  for example, which has 5 possible values, so it still fits in a single byte.

Perhaps the most useful application of this optimization are pointers and references within an. Since Rust doesn't have, they can never be zero. This allows the compiler to represent the  variant as zero, so an   or   still has the same size as   or. This is sometimes called a niche optimization, since pointers have a niche (an illegal value) that is filled with an enum variant.

A special case of this optimization is an enum with no variants or the never type. Since a value of such a type can't be constructed, it can always be optimized away: