---
# System prepended metadata

title: 'If, match, if let'

---

# 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)
