# If, match, if let ## if ```(rust) let n = 5; if n < 0 { print!("{} is negative", n); } else if n > 0 { print!("{} is positive", n); } else { print!("{} is zero", n); } ``` - each condition must be expression of `bool` type - Rust doesn't implicitly convert numbers or pointers to Boolean values - condition doesn't have to be surronded by parenthesis - no `;` at the end of block - all blocks must return same type ```(rust) let suggested_pet = if with_wings { Pet::Buzzard } else { Pet::Hyena }; // ok let favorite_number = if user.is_hobbit() { "eleventy-one" } else { 9 }; // error ``` ## match ```(rust) let number = 13; // TODO ^ Try different values for `number` println!("Tell me about {}", number); match number { // Match a single value 1 => println!("One!"), // Match several values 2 | 3 | 5 | 7 | 11 => println!("This is a prime"), // TODO ^ Try adding 13 to the list of prime values // Match an inclusive range 13..=19 => println!("A teen"), // Handle the rest of cases _ => println!("Ain't special"), // TODO ^ Try commenting out this catch-all arm } ``` - something like switch statement in C - matching *arm* - all cases must be covered - `_` wildcard pattern matches everything - like `default` case - comma after each arm may be dropped if expression is a block - Rust checks the given value against each arm in order, starting with the first - when pattern matches, expression is evaluated and `match` is completed ## if let ```(rust) let optional = Some(7); match optional { Some(i) => { println!("This is a really long string and `{:?}`", i); // ^ Needed 2 indentations just so we could destructure // `i` from the option. }, _ => {}, // ^ Required because `match` is exhaustive. Doesn't it seem // like wasted space? }; ``` ```(rust) let number = Some(7); let letter: Option<i32> = None; let emoticon: Option<i32> = None; // The `if let` construct reads: "if `let` destructures `number` into // `Some(i)`, evaluate the block (`{}`). if let Some(i) = number { println!("Matched {:?}!", i); } // If you need to specify a failure, use an else: if let Some(i) = letter { println!("Matched {:?}!", i); } else { // Destructure failed. Change to the failure case. println!("Didn't match a number. Let's go with a letter!"); } ``` - `match` does everything what `if let` does - `if let` expression is just shorthand for a `match` with just one pattern ### Ternary operator - Does not have ternary operator, it has been removed in 2012 - [GitHub](https://github.com/rust-lang/rust/issues/1698)