for ループ
for と range
for in 構文は、Iterator を反復処理するために使用できます。 イテレータを作成する最も簡単な方法の 1 つは、範囲記法 a..b を使用することです。これは a(含む)から b (含まない)までの値を 1 ずつ生成します。
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); } } }
a>b の場合でもコードはコンパイルできますが、ループは 決して実行されないことに注意してください。
for i in 10..1{ println!("fizzbuzz"); }
カウントダウンしたい場合は、代わりに .rev() を使用する必要があります
for i in (1..10).rev(){ println!("fizzbuzz"); }
for とイテレータ
for in 構文は、いくつかの方法で Iterator と相互作用できます。 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 ^ & を削除して、単に "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), } } // `names` は「ムーブ」されており、もう使用できません。 // コンパイラエラーを確認するには、下の行をアンコメントしてみてください。 // println!("names: {:?}", names); }
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 の分岐の型に注目してください。これが反復の種類における 重要な違いです。型の違いは、当然ながら実行可能な操作の違いを意味します。