Rust conditionals

From wikinotes

if statement

if num < 5 {
    // ..
} else if {
    // ..
} else {
    // ..
}

assign if

let weather = if season == "fall" { "lovely" } else { "fine I guess" } // ternary operator

match

Basics

Like a switch statement,
where compiler ensures that all possible options in datatype's range are handled,
that ensures the output type is the same for all branches (panic!()/break/return also allowed).

Especially useful for enums.

In the following case, if _ was omitted
you'd need to ensure the full range of possible i32 numbers were supported!.

// if num is '1', returns 'a'
// if num is >2, returns 'c'
let result = match num {
    1 => "a",
    2 => "b",
    _ => "c",   // anything other than 1 or 2
}

You can match multiple values

let result = match num {
    1 | 3 | 5 => "one three or five",
    _ => "something else"
}

Matching Enums

When matching a parametrized enum, you can access the tuple/struct/value that is bound to it

enum Pet {
    Cat(String, u8),
    Dog{name: String, age: u8},
    Lizard(u8),
}

let pet = Pet::Lizard(5);
match pet {
    Pet::Cat(name, age) => { format!("cat, name={}, age={}", name, age) },
    Pet::Dog(dog)       => { format!("dog, name={dog.name}, age={dog.age}") },
    Pet::Lizard(age)    => { format!("lizard, age={}", age) }
}

Matching Option

Option is just an enum, generally if you don't have a specific behaviour for None,
you return a new None in that branch.
However this an opportunity to fail if it is an appropriate location for it.

match some_value {
    Some(x) => "you received a value!",
    None    => None,
}

Matching Ranges

match val {
    i32::MIN..0 => "less than zero",
    0..5 => "is zero to five",
    5..i32::MAX => "is over five",
}
use std::cmp::Ordering;

// todo

if let

if let is essentially a one-branch match,
only caring about the value if it is non-none.
if my_value is None, then it returns None and the block does not run.

it does not take advantage of exhaustiveness checks.

if let Some(x) = my_value {
    println!("The value {} was bound!!", x);
}