100 exercises to learn Rust

This commit is contained in:
LukeMathWalker
2024-05-12 22:21:03 +02:00
commit 5edebf6cf2
309 changed files with 13173 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
# Concise branching
Your solution to the previous exercise probably looks like this:
```rust
impl Ticket {
pub fn assigned_to(&self) -> &String {
match &self.status {
Status::InProgress { assigned_to } => assigned_to,
Status::Done | Status::ToDo => {
panic!("Only `In-Progress` tickets can be assigned to someone"),
}
}
}
}
```
You only care about the `Status::InProgress` variant.
Do you really need to match on all the other variants?
New constructs to the rescue!
## `if let`
The `if let` construct allows you to match on a single variant of an enum,
without having to handle all the other variants.
Here's how you can use `if let` to simplify the `assigned_to` method:
```rust
impl Ticket {
pub fn assigned_to(&self) -> &String {
if let Status::InProgress { assigned_to } = &self.status {
assigned_to
} else {
panic!("Only `In-Progress` tickets can be assigned to someone");
}
}
}
```
## `let/else`
If the `else` branch is meant to return early (a panic counts as returning early!),
you can use the `let/else` construct:
```rust
impl Ticket {
pub fn assigned_to(&self) -> &String {
let Status::InProgress { assigned_to } = &self.status else {
panic!("Only `In-Progress` tickets can be assigned to someone");
};
assigned_to
}
}
```
It allows you to assign the destructured variable without incurring
any "right drift", i.e. the variable is assigned at the same indentation level
as the code that precedes it.
## Style
Both `if let` and `let/else` are idiomatic Rust constructs.
Use them as you see fit to improve the readability of your code,
but don't overdo it: `match` is always there when you need it.
## References
- The exercise for this section is located in `exercises/05_ticket_v2/04_if_let`