for と range - Rust By Example
Description: Rust by Example (RBE) is a collection of runnable examples that illustrate various Rust concepts and standard libraries.

## Keyboard shortcuts

Press `←` or `→` to navigate between chapters

Press `S` or `/` to search in the book

Press `?` to show this help

Press `Esc` to hide this help

# forループ

## for と range

`for in`構文を用いることで、イテレータのそれぞれの要素に対して処理をすることが可能です。イテレータを作る最も単純な方法は`a..b`のような範囲記法です。これは「`a`」から「`b`のひとつ前」までの要素を順に生成します。

では`while`の代わりに`for`を用いてFizzBuzzを書いてみましょう。

    fn main() {
        // `n`は1, 2, ...., 100のそれぞれの値を取ります。
        for n in 1..101 {
            if n % 15 == 0 {
                println!("fizzbuzz");
            } else if n % 3 == 0 {
                println!("fizz");
            } else if n % 5 == 0 {
                println!("buzz");
            } else {
                println!("{}", n);
            }
        }
    }

上記の代わりに`a..=b`を用いると、両端の値を含む範囲を指定できます。上記の例は次のように書けます。

    fn main() {
        // `n`は1, 2, ...., 100のそれぞれの値を取ります。
        for n in 1..=100 {
            if n % 15 == 0 {
                println!("fizzbuzz");
            } else if n % 3 == 0 {
                println!("fizz");
            } else if n % 5 == 0 {
                println!("buzz");
            } else {
                println!("{}", n);
            }
        }
    }

## forとイテレータ

`for in`構文はイテレータとさまざまな方法でやり取りできます。Iteratorトレイトの章で説明したように、デフォルトでは`for`ループにおいて`into_iter`関数がコレクションに対して適用されます。しかし、コレクションをイテレータに変換する方法はこれだけではありません。

`into_iter`、`iter`、`iter_mut`はいずれもコレクションのイテレータへの変換を行いますが、データの「見せ方」の違いにより、そのやり方はそれぞれ異なります。

- `iter` - この関数は、各周回においてコレクションの要素を借用します。よってコレクションには手を加えないので、ループの実行後もコレクションを再利用できます。

    fn main() {
        let names = vec!["Bob", "Frank", "Ferris"];

        for name in names.iter() {
            match name {
                &"Ferris" => println!("There is a rustacean among us!"),
                // TODO ^ Try deleting the & and matching just "Ferris"
                _ => println!("Hello {}", name),
            }
        }

        println!("names: {:?}", names);
    }

- `into_iter` - この関数はコレクションからデータを取り出すので、各周回において要素のデータそのものが提供されます。データを取り出してしまうと、データはループ内に「移動」してしまうので、ループ実行後にコレクションを再利用することはできません。

    fn main() {
        let names = vec!["Bob", "Frank", "Ferris"];

        for name in names.into_iter() {
            match name {
                "Ferris" => println!("There is a rustacean among us!"),
                _ => println!("Hello {}", name),
            }
        }

        println!("names: {:?}", names);
        // FIXME ^ この行をコメントアウトしましょう
    }

- `iter_mut` - この関数はコレクションの各要素をミュータブル（変更可能）で借用するので、コレクションの要素をその場で変更できます。

    fn main() {
        let mut names = vec!["Bob", "Frank", "Ferris"];

        for name in names.iter_mut() {
            *name = match name {
                &mut "Ferris" => "There is a rustacean among us!",
                _ => "Hello",
            }
        }

        println!("names: {:?}", names);
    }

上記に示した3つのコードにおいて、`match`の選択肢の型の違いに注意してください。ここがそれぞれの方法の違いを生む鍵になっています。型が異なれば、当然ながらそれに対して行える処理も変わります。

### 参照

イテレータ