Rust conditionals

From wikinotes
Revision as of 17:51, 8 February 2023 by Will (talk | contribs) (→‎Basics)

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.

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,
}

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);
}