rust/src/doc/trpl/match.md

64 lines
2.1 KiB
Markdown
Raw Normal View History

% Match
2015-04-18 14:32:26 -05:00
Often, a simple [`if`][if]/`else` isnt enough, because you have more than two
possible options. Also, conditions can get quite complex. Rust
has a keyword, `match`, that allows you to replace complicated `if`/`else`
groupings with something more powerful. Check it out:
2015-04-10 11:03:30 -05:00
```rust
let x = 5;
match x {
1 => println!("one"),
2 => println!("two"),
3 => println!("three"),
4 => println!("four"),
5 => println!("five"),
_ => println!("something else"),
}
```
2015-04-18 14:32:26 -05:00
[if]: if.html
`match` takes an expression and then branches based on its value. Each arm of
2015-04-10 11:03:30 -05:00
the branch is of the form `val => expression`. When the value matches, that arms
expression will be evaluated. Its called `match` because of the term pattern
matching, which `match` is an implementation of. Theres an [entire section on
2015-04-18 14:32:26 -05:00
patterns][patterns] that covers all the patterns that are possible here.
2015-04-10 11:03:30 -05:00
[patterns]: patterns.html
2015-04-18 14:32:26 -05:00
So whats the big advantage? Well, there are a few. First of all, `match`
enforces exhaustiveness checking. Do you see that last arm, the one with the
underscore (`_`)? If we remove that arm, Rust will give us an error:
```text
error: non-exhaustive patterns: `_` not covered
```
In other words, Rust is trying to tell us we forgot a value. Because `x` is an
2015-04-18 14:32:26 -05:00
integer, Rust knows that it can have a number of different values for
example, `6`. Without the `_`, however, there is no arm that could match, and
so Rust refuses to compile the code. `_` acts like a catch-all arm. If none
of the other arms match, the arm with `_` will, and since we have this
catch-all arm, we now have an arm for every possible value of `x`, and so our
program will compile successfully.
`match` is also an expression, which means we can use it on the right-hand
2015-04-10 11:03:30 -05:00
side of a `let` binding or directly where an expression is used:
2015-04-10 11:03:30 -05:00
```rust
let x = 5;
2015-05-10 00:10:34 -05:00
let number = match x {
2015-04-10 11:03:30 -05:00
1 => "one",
2 => "two",
3 => "three",
4 => "four",
5 => "five",
_ => "something else",
};
```
2015-04-18 14:32:26 -05:00
Sometimes its a nice way of converting something from one type to another.