Rust Language

Understanding `for &value in &vec` in Rust: Pattern Matching and Automatic Dereferencing

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:

  1. &a obtains a reference of type &i32 for each element of the Vec<i32>.
  2. The for &value syntax immediately dereferences this reference via pattern matching, extracting the value value (of type i32).

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 a Vec<i32> → Ownership of the contained values resides with vec.
  • &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 &veclet value = *value_ref; clarifies its behavior.