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 構文は、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_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!"),
            // 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 の分岐の型に注目してください。これが反復の種類における 重要な違いです。型の違いは、当然ながら実行可能な操作の違いを意味します。

関連項目:

イテレータ