forループ

forとrange

for in文はイテレータを使って繰り返し処理をするのに使います。 イテレータを作る最も簡単な方法の一つは、a..bのように書くことです。 これはa(含む)からb(除く)までの数値を順に産出(yield)します。

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文はイテレータといくつかの方法で相互作用することができます。 イテレータトレイトの節で議論したように、デフォルトでforループは コレクションのinto_iter関数を実行しますが、これだけがコレクションを イテレータに変換するわけではありません。

into_iteriteriter_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!"),  // 私達のようなRustaceanがいます
            _ => println!("Hello {}", name),
        }
    }
}
  • into_iter - これはコレクションを消費し、各繰り返しで正確なデータを提供します。 一度コレクションが消費されると、データを「move」し、もはや再利用できないようになります。
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),
        }
    }
}
  • 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);
}

上記の例ではmatch分岐の型が、繰り返しのタイプの違いを示すキーになります。 タイプの違いによって、違った振る舞いができることが分かるでしょう。

こちらも参照: