diff --git a/book.toml b/book.toml index b078e3c89bb..7e6e1558b44 100644 --- a/book.toml +++ b/book.toml @@ -213,6 +213,7 @@ use-boolean-and = true "traits/read-write.html" = "../std-traits/read-and-write.html" "traits/trait-bounds.html" = "../generics/trait-bounds.html" "traits/trait-objects.html" = "../smart-pointers/trait-objects.html" +"tuples-and-arrays/match.html" = "../pattern-matching/match.html" "unsafe.html" = "unsafe-rust/unsafe.html" "unsafe/calling-unsafe-functions.html" = "../unsafe-rust/unsafe-functions.html" "unsafe/extern-functions.html" = "../unsafe-rust/unsafe-functions.html" diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 13e5e575435..ae2662650f9 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -49,8 +49,7 @@ - [Tuples and Arrays](tuples-and-arrays.md) - [Tuples and Arrays](tuples-and-arrays/tuples-and-arrays.md) - [Array Iteration](tuples-and-arrays/iteration.md) - - [Pattern Matching](tuples-and-arrays/match.md) - - [Destructuring](tuples-and-arrays/destructuring.md) + - [Patterns and Destructuring](tuples-and-arrays/destructuring.md) - [Exercise: Nested Arrays](tuples-and-arrays/exercise.md) - [Solution](tuples-and-arrays/solution.md) - [References](references.md) @@ -73,6 +72,7 @@ - [Welcome](welcome-day-2.md) - [Pattern Matching](pattern-matching.md) + - [Matching Values](pattern-matching/match.md) - [Destructuring](pattern-matching/destructuring.md) - [Let Control Flow](pattern-matching/let-control-flow.md) - [Exercise: Expression Evaluation](pattern-matching/exercise.md) diff --git a/src/tuples-and-arrays/match.md b/src/pattern-matching/match.md similarity index 95% rename from src/tuples-and-arrays/match.md rename to src/pattern-matching/match.md index 808e2e77d48..fcd4a779811 100644 --- a/src/tuples-and-arrays/match.md +++ b/src/pattern-matching/match.md @@ -2,7 +2,7 @@ minutes: 10 --- -# Pattern Matching +# 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. @@ -24,7 +24,7 @@ fn main() { ``` The `_` pattern is a wildcard pattern which matches any value. The expressions -_must_ be irrefutable, meaning that it covers every possibility, so `_` is often +_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 diff --git a/src/tuples-and-arrays/destructuring.md b/src/tuples-and-arrays/destructuring.md index d959b827327..dfc8dcea00b 100644 --- a/src/tuples-and-arrays/destructuring.md +++ b/src/tuples-and-arrays/destructuring.md @@ -2,44 +2,55 @@ minutes: 5 --- -# Destructuring +# Patterns and Destructuring -Destructuring is a way of extracting data from a data structure by writing a -pattern that is matched up to the data structure, binding variables to -subcomponents of the data structure. - -You can destructure tuples and arrays by matching on their elements: - -## Tuples +When working with tuples and other structured values it's common to want to +extract the inner values into local variables. This can be done manually by +directly accessing the inner values: ```rust,editable -fn main() { - describe_point((1, 0)); +fn print_tuple(tuple: (i32, i32)) { + let left = tuple.0; + let right = tuple.1; + println!("left: {left}, right: {right}"); } +``` + +However, Rust also supports using pattern matching to destructure a larger value +into its constituent parts: -fn describe_point(point: (i32, i32)) { - match point { - (0, _) => println!("on Y axis"), - (_, 0) => println!("on X axis"), - (x, _) if x < 0 => println!("left of Y axis"), - (_, y) if y < 0 => println!("below X axis"), - _ => println!("first quadrant"), - } +```rust,editable +fn print_tuple(tuple: (i32, i32)) { + let (left, right) = tuple; + println!("left: {left}, right: {right}"); } ``` -## Arrays +This works with any kind of structured value: ```rust,editable -{{#include ../../third_party/rust-by-example/destructuring-arrays.rs}} +struct Foo { + a: i32, + b: bool, +} + +fn print_foo(foo: Foo) { + let Foo { a, b } = foo; + println!("a: {a}, b: {b}"); +} ```
-- Create a new array pattern using `_` to represent an element. -- Add more values to the array. -- Point out that how `..` will expand to account for different number of - elements. -- Show matching against the tail with patterns `[.., b]` and `[a@..,b]` +- The patterns used here are "irrefutable", meaning that the compiler can + statically verify that the value on the right of `=` has the same structure as + the pattern. +- A variable name is an irrefutable pattern that always matches any value, hence + why we can also use `let` to declare a single variable. +- Rust also supports using patterns in conditionals, allowing for equality + comparison and destructuring to happen at the same time. This form of pattern + matching will be discussed in more detail later. +- Edit the examples above to show the compiler error when the pattern doesn't + match the value being matched on.