Explanation of `for &value in &vec` in Rust
In Rust's loop syntax, you often see vectors iterated using the `&` prefix, as shown below.
let a = vec![10, 20, 30];
for &value in &a {
println!("{}", value);
}
While this syntax may not be immediately intuitive, it's a shorthand notation based on Rust's pattern matching and ownership/borrowing model.
Meaning and Expansion of for &value in &a
This loop automatically performs the following actions:
&a
obtains a reference of type&i32
for each element of theVec<i32>
.- The
for &value
syntax immediately dereferences this reference via pattern matching, extracting the valuevalue
(of typei32
).
A more explicit version would be:
for value_ref in &a {
let value = *value_ref;
println!("{}", value);
}
Here, value_ref
has the type &i32
, and *value_ref
retrieves the actual value (i32
) from the reference (borrow).
The Implied _ref
In Rust, code like for x in &vec
iterates by passing a reference to each element of vec
to x
. Therefore, for &value in &vec
essentially extracts a reference, value_ref
, one by one, and expands it as *value_ref
. This process is expressed as a syntactic shorthand.
// The underlying process can be visualized as:
for value_ref in &vec {
let value = *value_ref;
}
Thus, although value_ref
isn't explicitly declared, it can be considered an internal variable handled by Rust.
From an Ownership/Borrowing Perspective
Rust rigorously manages value ownership.
vec
is aVec<i32>
→ Ownership of the contained values resides withvec
.&vec
creates a borrow of that ownership.- Within the loop, each element is borrowed as
&i32
. *value_ref
performs dereferencing of the borrow to read the contained value.
In essence, *value_ref
is a mechanism compliant with Rust's borrowing rules, allowing temporary access to the value from a reference.
The following diagram illustrates the process behind for &value in &a
.
a = vec![10, 20, 30]
↓
+-------------------+
| 10 20 30 | ← Ownership resides with a
+-------------------+
↓
&a (Borrow)
↓
+------------------------+
| &10 | &20 | &30 | ← Each element is &i32
+------------------------+
↓ ↓
*value_ref *value_ref ← Dereference to obtain value
↓ ↓
value=10 value=20
Summary
for &value in &vec
is a syntax that borrows vector elements by reference while simultaneously dereferencing to obtain their values.- This syntax leverages Rust's ownership model and pattern matching.
- Understanding the underlying process as
for value_ref in &vec
→let value = *value_ref;
clarifies its behavior.