Skip to content

Commit

Permalink
Add a slide on match to control flow section (#2515)
Browse files Browse the repository at this point in the history
  • Loading branch information
randomPoison authored Dec 17, 2024
1 parent 2ff30ed commit e902b1e
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 13 deletions.
1 change: 1 addition & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
- [Solution](types-and-values/solution.md)
- [Control Flow Basics](control-flow-basics.md)
- [`if` Expressions](control-flow-basics/if.md)
- [`match` Expressions](control-flow-basics/match.md)
- [Loops](control-flow-basics/loops.md)
- [`for`](control-flow-basics/loops/for.md)
- [`loop`](control-flow-basics/loops/loop.md)
Expand Down
72 changes: 72 additions & 0 deletions src/control-flow-basics/match.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
minutes: 5
---

# `match` Expressions

`match` can be used to check a value against one or more options:

```rust,editable
fn main() {
let val = 1;
match val {
1 => println!("one"),
10 => println!("ten"),
100 => println!("one hundred"),
_ => {
println!("something else");
}
}
}
```

Like `if` expressions, `match` can also return a value;

```rust,editable
fn main() {
let flag = true;
let val = match flag {
true => 1,
false => 0,
};
println!("The value of {flag} is {val}");
}
```

<details>

- `match` arms are evaluated from top to bottom, and the first one that matches
has its corresponding body executed.

- There is no fall-through between cases the way that `switch` works in other
languages.

- The body of a `match` arm can be a single expression or a block. Technically
this is the same thing, since blocks are also expressions, but students may
not fully understand that symmetry at this point.

- `match` expressions need to be exhaustive, meaning they either need to cover
all possible values or they need to have a default case such as `_`.
Exhaustiveness is easiest to demonstrate with enums, but enums haven't been
introduced yet. Instead we demonstrate matching on a `bool`, which is the
simplest primitive type.

- This slide introduces `match` without talking about pattern matching, giving
students a chance to get familiar with the syntax without front-loading too
much information. We'll be talking about pattern matching in more detail
tomorrow, so try not to go into too much detail here.

## More to Explore

- To further motivate the usage of `match`, you can compare the examples to
their equivalents written with `if`. In the second case matching on a `bool`
an `if {} else {}` block is pretty similar. But in the first example that
checks multiple cases, a `match` expression can be more concise than
`if {} else if {} else if {} else`.

- `match` also supports match guards, which allow you to add an arbitrary
logical condition that will get evaluated to determine if the match arm should
be taken. However talking about match guards requires explaining about pattern
matching, which we're trying to avoid on this slide.

</details>
18 changes: 5 additions & 13 deletions src/pattern-matching/match.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ minutes: 10
# Matching Values

The `match` keyword lets you match a value against one or more _patterns_. The
comparisons are done from top to bottom and the first match wins.

The patterns can be simple values, similarly to `switch` in C and C++:
patterns can be simple values, similarly to `switch` in C and C++, but they can
also be used to express more complex conditions:

```rust,editable
#[rustfmt::skip]
Expand All @@ -23,18 +22,11 @@ fn main() {
}
```

The `_` pattern is a wildcard pattern which matches any value. The expressions
_must_ be exhaustive, meaning that it covers every possibility, so `_` is often
used as the final catch-all case.

Match can be used as an expression. Just like `if`, each match arm must have the
same type. The type is the last expression of the block, if any. In the example
above, the type is `()`.

A variable in the pattern (`key` in this example) will create a binding that can
be used within the match arm.
be used within the match arm. We will learn more about this on the next slide.

A match guard causes the arm to match only if the condition is true.
A match guard causes the arm to match only if the condition is true. If the
condition is false the match will continue checking later cases.

<details>

Expand Down

0 comments on commit e902b1e

Please sign in to comment.