# Enumerations

An enumeration 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:

    # #![allow(unused_variables)]
    #fn main() {
    enum Animal {
        Dog,
        Cat,
    }

    let mut a: Animal = Animal::Dog;
    a = Animal::Cat;
    #}

Enumeration constructors can have either named or unnamed fields:

    # #![allow(unused_variables)]
    #fn main() {
    enum Animal {
        Dog (String, f64),
        Cat { name: String, weight: f64 },
    }

    let mut a: Animal = Animal::Dog("Cocoa".to_string(), 37.2);
    a = Animal::Cat { name: "Spotty".to_string(), weight: 2.7 };
    #}

In this example, `Cat` is a struct-like enum variant, whereas `Dog` is simply called an enum variant. Each enum instance has a discriminant which is an integer associated to it that is used to determine which variant it holds.

## C-like Enumerations

If there is no data attached to any of the variants of an enumeration it is called a c-like enumeration. If a discriminant isn't specified, they start at zero, and add one for each variant, in order. Each enum value is just its discriminant which you can specify explicitly:

    # #![allow(unused_variables)]
    #fn main() {
    enum Foo {
        Bar,            // 0
        Baz = 123,
        Quux,           // 124
    }
    #}

The right hand side of the specification is interpreted as an `isize` value, but the compiler is allowed to use a smaller type in the actual memory layout. The `repr` attribute can be added in order to change the type of the right hand side and specify the memory layout.

You can also cast a c-like enum to get its discriminant:

    # #![allow(unused_variables)]
    #fn main() {
    # enum Foo { Baz = 123 }
    let x = Foo::Baz as u32; // x is now 123u32
    #}

This only works as long as none of the variants have data attached. If it were `Baz(i32)`, this is disallowed.