Progrust Library.

// dictionary

for式.

for式は、イテレータが生み出す要素を順に取り出し、要素ごとに本体のブロックを実行するループです。for パターン in 式 { ... }の形で書き、inの右側にはイテレータに変換できる値(範囲式配列型ベクタ(Vec)など)を置きます1。要素がなくなれば自動で終了するため繰り返し回数の管理が要らず、3種類のループの中で最もよく使う構文です。名前のとおり全体が1つのですが、その値は常にユニット型()で、loop式と違いbreakで値を返せません。

fn main() {
    let prices = [120, 250, 80]; // 買い物かごの中身
    let mut total = 0;
    for price in prices {
        total += price;
    }
    println!("合計: {total}円");
}
Playgroundで開く

コレクションの渡し方は3通り

ベクタのようなコレクションは、inにそのまま渡すか参照で渡すかで、取り出せる要素の型が変わります。

書き方 要素の型 主な用途
for x in &v &T(参照) 読み取りだけ行う
for x in &mut v &mut T(排他参照) 要素を書き換える
for x in v T(所有権が移る) 要素を消費する

そのまま渡すと所有権がループに移り、ベクタのようなCopyでない型ではループの後で元の変数を使えなくなります(冒頭の例の配列は要素がCopyのため配列ごとコピーが渡り、後でも使えます)。読み取りだけなら&vで渡すのが基本です。

補足

添字が必要なとき — enumerate

要素と一緒に「何番目か」も使いたいときは、添字を自前で管理するのではなくenumerateを使います。添字と要素のペアがタプル型の値として順に得られます(添字は0始まり)。

fn main() {
    let menu = ["カレー", "ラーメン", "うどん"];
    for (index, name) in menu.iter().enumerate() {
        println!("{}番: {name}", index + 1); // 表示用に+1します(enumerate自体は0始まり)
    }
}
Playgroundで開く
for式はloop式への糖衣構文

for式はコンパイル時に、IntoIterator::into_iterでイテレータを作り、loopの中でIterator::nextを呼び続ける形へ展開されます1nextOption型Some(値)を返す間だけ本体を実行し、Noneになったらbreakします。inの左側には、このSomeから取り出した値が束縛されるため、必ずマッチするパターン(irrefutableパターン)しか書けません。

他言語のfor文との違い

JavaScriptやC言語にあるfor (let i = 0; i < 3; i++)のような「カウンタ変数を初期化・条件判定・更新する」形式のfor文は、Rustには存在しません(forの構文はイテレータを回す形式だけです1)。

言語 代表的な書き方
JavaScript(C形式) for (let i = 0; i < 3; i++) { ... }
JavaScript(for...of for (const item of items) { ... }
Rust for i in 0..3 { ... }for item in &items { ... }

Rustのforが相当するのはJavaScriptのfor...ofで、カウンタで回したいときは範囲式を渡します。添字と終了条件を手書きするカウンタ形式は、条件の書き間違いで配列の範囲外を指してパニックしたり要素を取りこぼしたりするバグの温床になるため、Rustではイテレータ形式のforが安全かつ簡潔な定番とされています2

Footnotes

  1. The Rust Reference: Loops and other breakable expressions 2 3

  2. The Rust Programming Language: Control Flow

この辞書が使われているページ

backlinks 8

  1. 辞書loop式
  2. 辞書while式
  3. 辞書ループラベル
  4. 辞書範囲式
  5. 辞書
  6. 動かして学ぶRustプログラミング問題集 › 第3章 制御フロー
  7. 動かして学ぶRustプログラミング問題集 › 第5章 タプルと配列・スライス
  8. 動かして学ぶRustプログラミング問題集 › 第6章 文字列とベクタ