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_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!"), // 私達のような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分岐の型が、繰り返しのタイプの違いを示すキーになります。
タイプの違いによって、違った振る舞いができることが分かるでしょう。