Rust lang

Rustにおける for &value in &vec の動作解説:パターンマッチと参照の自動デリファレンス

Rustにおける `for &value in &vec` の動作解説

Rustのループ構文では、以下のようにベクタを `&` を付けてループする書き方をよく見かけます。

let a = vec![10, 20, 30];

for &value in &a {
    println!("{}", value);
}

この構文は一見直感的ではないかもしれませんが、Rustのパターンマッチング所有権・借用モデルに基づいた省略記法です。

for &value in &a の意味と展開

このループでは以下のことが自動的に行われています。

  1. &a によって、Vec<i32> の各要素に対して &i32参照が得られる。
  2. for &value という構文が、その参照をパターンマッチにより即座にデリファレンスし、valuei32)を取り出す。

より展開された形で書くと以下のようになります:

for value_ref in &a {
    let value = *value_ref;
    println!("{}", value);
}

このとき、value_ref の型は &i32 であり、*value_ref によって参照(borrow)から実体の値(i32)を取得しています。

_ref がつくイメージ

Rustでは、for x in &vec のようなコードは「vec の要素への参照を x に1つずつ渡している」動作になります。 そのため for &value in &vec は、実際には value_ref という参照を1つずつ取り出し、それを *value_ref として展開するような処理を、構文上の省略で表現しています。

// イメージとしては次のように展開されている
for value_ref in &vec {
    let value = *value_ref;
}

このように、value_ref は明示されていないだけで、Rustが内部的に扱っている変数と見なすことができます。

所有権・借用の観点から見ると

Rustでは、値の所有権を強く管理しています。

  • vecVec<i32> → 中身の値の所有権は vec にある
  • &vec によって、その所有権を借りる(borrow)
  • ループの中では各要素を &i32 として借用する
  • *value_ref を使うことでその借用を**参照外し(デリファレンス)**して中身を読み取る

つまり、*value_ref は「参照から中身を一時的に取り出して読みたい」という、Rustの借用ルールに則った読み取り手段なのです。

以下の図は for &value in &a の背後で行われている処理のイメージを示しています。

          a = vec![10, 20, 30]
                    ↓
           +-------------------+
           |   10   20   30    |  ← 所有権は a にある
           +-------------------+
                    ↓
               &a(借用)
                    ↓
        +------------------------+
        |  &10  |  &20  |  &30   |  ← 各要素は &i32
        +------------------------+
             ↓        ↓
       *value_ref   *value_ref   ← デリファレンスで値取得
             ↓        ↓
         value=10  value=20

まとめ

  • for &value in &vec は、ベクタ要素を参照で借用しつつ、即座にデリファレンスして値を得る構文。
  • この構文は、Rustの所有権モデルとパターンマッチを活かした書き方
  • 背景では for value_ref in &veclet value = *value_ref; という処理が行われていると理解すれば、挙動が明確になる。