rust/src/doc/trpl/if-let.md

83 lines
1.7 KiB
Markdown
Raw Normal View History

% if let
2015-04-20 16:39:38 -05:00
`if let` allows you to combine `if` and `let` together to reduce the overhead
of certain kinds of pattern matches.
For example, lets say we have some sort of `Option<T>`. We want to call a function
on it if its `Some<T>`, but do nothing if its `None`. That looks like this:
```rust
# let option = Some(5);
# fn foo(x: i32) { }
match option {
Some(x) => { foo(x) },
None => {},
}
```
We dont have to use `match` here, for example, we could use `if`:
```rust
# let option = Some(5);
# fn foo(x: i32) { }
if option.is_some() {
let x = option.unwrap();
foo(x);
}
```
Neither of these options is particularly appealing. We can use `if let` to
do the same thing in a nicer way:
```rust
# let option = Some(5);
# fn foo(x: i32) { }
if let Some(x) = option {
foo(x);
}
```
If a [pattern][patterns] matches successfully, it binds any appropriate parts of
the value to the identifiers in the pattern, then evaluates the expression. If
the pattern doesnt match, nothing happens.
2015-10-14 17:16:13 -05:00
If you want to do something else when the pattern does not match, you can
2015-04-20 16:39:38 -05:00
use `else`:
```rust
# let option = Some(5);
# fn foo(x: i32) { }
# fn bar() { }
if let Some(x) = option {
foo(x);
} else {
bar();
}
```
## `while let`
In a similar fashion, `while let` can be used when you want to conditionally
loop as long as a value matches a certain pattern. It turns code like this:
```rust
# let option: Option<i32> = None;
loop {
match option {
Some(x) => println!("{}", x),
None => break,
2015-04-20 16:39:38 -05:00
}
}
```
Into code like this:
```rust
# let option: Option<i32> = None;
while let Some(x) = option {
println!("{}", x);
}
```
[patterns]: patterns.html