Yomiage
メニュー

Rust実践講座 10:クロージャとイテレータで変換する

更新 2026/9/27 6:22:11 公開

投稿者: しゅりりん

到達点は、借用と所有権の違いを保ちながら、抽出と集計を書くことです。前提は第08・09回です。

取り出し方で所有関係が変わる

Vecに対するiterは共有参照、iter_mutは可変参照、into_iterはVecを消費して所有する要素を取り出す使い方ができます。同じ「繰り返し」に見えても、元のデータを後で使えるかが違います。

fn main() {
    let mut values = vec![10, 20, 30];
    let threshold = 15;
    let total: i32 = values.iter()
        .copied()
        .filter(|value| *value >= threshold)
        .sum();
    println!("{total}");
    for value in values.iter_mut() { *value += 1; }
    let labels: Vec<String> = values.into_iter()
        .enumerate()
        .map(|(index, value)| format!("{}: {value}", index + 1))
        .collect();
    println!("{:?}", labels);
}

src/main.rsでの出力は50、11・21・31に番号を付けたリストです。copiedはCopyできる値を参照から取り出します。filterは判定のため要素を借りるので、ここでは引数を参照外しして比較しています。

クロージャは周囲の値を使える

縦棒で囲んだ引数の後ろがクロージャの本体です。例のfilterは周囲のthresholdを使います。クロージャは使い方に応じて共有借用、可変借用、所有権の取得を行います。Fn、FnMut、FnOnceは、どう呼び出せるかを表すトレイトです。

moveを付けると捕捉する値をクロージャへ移しますが、moveだから必ず一回しか呼べないわけではありません。中で所有物を消費するかなどが関係します。呼び出し方と捕捉方法を区別します。

mapなどは遅延して処理され、collect、sum、forなどで消費して初めて進みます。副作用をmapへ隠すより、変換はmap、明示的な操作はforというように読み手へ意図を示します。

練習と解答

練習:into_iterの後にvaluesを表示できない理由と、元のVecを残す修正を説明します。

解答:今回のinto_iterはVecを消費するためです。values.iter() で借用し、必要なCopy値はcopiedで取り出すか、参照を使って表示文字列を作ります。全部cloneする前に、借用で足りるか考えましょう。

公式資料

クロージャとイテレータが参照先です。


Rust全20回の目次 | 前の回 | 次の回

このブラウザでは Web Speech API が利用できません。

1 / 16 · 停止中