Rust Reference Patterns
A reference pattern matches against a reference instead of moving a value. The & shape matches a reference itself.
An & inside the pattern
Matching a reference against &x takes one & off each side. x binds the value behind the reference:
let point = &5;
match point {
&x => println!("x = {x}"),
}ref borrows instead of taking
A plain name would move the text out of the Option. ref binds by borrowing instead, so the Option keeps its text and stays usable:
let gift = Some(String::from("book"));
if let Some(ref title) = gift {
println!("the gift is a {title}");
}
println!("gift kept: {:?}", gift);ref mut borrows so you can change
Borrow mutably and you can change the value through the reference. The star follows the reference to the value behind it:
let mut score = Some(10);
if let Some(ref mut n) = score {
*n += 5;
}
println!("score = {:?}", score);Loops hand you references too
iter() lends each item, so name is a &str each round. A literal pattern is written with & in front of it:
let names = ["Rex", "Ferris"];
for name in names.iter() {
match name {
&"Ferris" => println!("found Ferris"),
_ => println!("someone else"),
}
}Example
fn main() {
let name = Some(String::from("Ferris"));
match name {
Some(ref s) => println!("borrowed {}", s),
None => println!("none"),
}
println!("still usable: {:?}", name);
let mut count = Some(5);
if let Some(ref mut n) = count {
*n += 1;
}
println!("count = {:?}", count);
}Key points
- Destructuring is not dereferencing: * follows a reference in an expression, while &, ref, and ref mut are shapes inside a pattern
- Both shapes let code look at a value without taking it.
In this example, Some(ref s) borrows the text instead of moving it. The arm prints borrowed Ferris through the reference s. Because nothing moved, name is still whole afterwards, and the second line prints it in full. Below, count holds Some(5). The pattern Some(ref mut n) borrows the number mutably. So *n += 1 raises it to 6. The last line shows count = Some(6). Two words, ref and ref mut, chose borrowing over taking.
Note
Modern Rust often adds the borrowing for you when a pattern meets a reference (called match ergonomics).
ref and & still earn their place: they say exactly what you meant, and older code is full of them.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Rust Playground
Exercise
In the pattern Some(ref s), what is s?