Course contentsShow
← Rust
Lesson 289 of 1,9103. Borrowing and ReferencesFree lesson

Using References in Pattern Matching

Destructure references into their constituent parts using pattern syntax.

In this lesson, you will learn how to destructure references directly within a match statement to access the data they point to without needing manual dereferencing.

Destructuring References

When you have a reference to a complex type—like a tuple or a struct—you often want to inspect the values inside without taking ownership of them. While you could dereference the entire value first (e.g., *my_ref), Rust allows you to "reach through" the reference using pattern matching. By placing the & symbol inside the match pattern, you tell the compiler to look at the data being pointed to.

Pattern Matching on Tuples

Imagine you have a reference to a tuple &(i32, i32). Instead of manually dereferencing the tuple, you can match on the structure directly:

let point = (10, 20);
let ref_point = &point;

match ref_point {
    &(x, y) => println!("The coordinates are {} and {}", x, y),
}

In the pattern &(x, y), the & tells Rust: "This pattern is matching against a reference, so please destructure the contents." Because x and y are integers (which implement the Copy trait), they are copied out of the tuple, leaving the original reference intact.

Handling Non-Copy Types

If you are matching on a type that cannot be copied, such as a String, you must be careful. If you try to match a &String and pull out the data, you would be attempting to move the string out of a reference, which the compiler will prevent. In these cases, you use the ref keyword inside the pattern to create a new reference to the inner field:

let name = String::from("Rust");
let ref_name = &name;

match ref_name {
    ref s => println!("The string is: {}", s),
}

Here, ref s creates a reference to the String inside the ref_name pointer. This allows you to inspect or borrow the inner data without attempting to move it out of the original memory location.

By combining & to destructure and ref to borrow, you can navigate complex data structures efficiently while strictly adhering to Rust’s ownership rules.

Key Takeaway: You can use & in patterns to destructure references into their parts, or ref to borrow specific fields while matching, allowing you to access interior data safely without needing to manually dereference.