Rust - Enumerations


Enums are great for categorical data, where something, like an IP address, can belong to one category, such as IPv4 or IPv6. Enums are heavily used in Rust, unlike in C++. Example:

enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter,
}

// Function that uses an enum as a parameter
fn coin_value(coin: Coin) -> u8 {
    match coin {
        Coin::Penny => 1,
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter => 25,
    }
}

// Enums can contain data
enum Message {
    Move { x: i32, y: i32 }, // Anonymous struct
    Write(String),
    ChangeColor(i32, i32, i32), // three i32 values
    Quit,
}

// Method of Message
impl Message {
    fn call(&self) {
        // Body
    }
}

fn main() {
    // Use the namespace syntax to choose a category
    let c = Coin::Dime;
    println!("Coin value: {}", coin_value(c));

    let m = Message::Write(String::from("hello"));
    m.call();
}

Option

Null references have caused lots of problems in other languages. To solve this, Rust created the Option enum. In the Option enum, there are two possibilities: Some (not null) and None (null). The Option enum will not interact with none Option data, thus you have to be aware of when using types that might be null, unlike C++ pointers 😁.

This enum is so popular in Rust that it is automatically loaded, Some and None can be used without namespacing them with Option.

The Option enum works well with the match expression, verifying that you cover both the null and not null cases.

Basic definition:

enum Option<T> {
    Some(T),
    None,
}

Example use:

// With namespaceing
let some_number = Option::Some(2);
// Without namespacing
let another_number = Some(3);
let some_string = Some("Daltie");

// "Null"
let absent_number: Option<i32> = None; // Need to specify the type that Null would be otherwise

// Options and none options do not interact with each other natively
let x: i8 = 3;
let y: Option<i8> = Some(5);

//let sum = x + y; // Breaks

Function example:

fn add_one(x: Option<i32>) -> Option<i32> {
    match x {
        None => None,
        Some(i) => Some(i + 1),
    }
}


fn main() {
    let three = Some(3);
    let four = add_one(three);
    let none = add_one(None);
}