イテレータ - 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

# イテレータ

`Iterator`トレイトは、例えば配列のような、要素の集合に対してイテレータを実装するためのトレイトです。

このトレイトは`next`の要素に相当するものを決定するためのメソッドのみを要求します。このメソッドは`impl`ブロック内で手動で実装するか、あるいは（配列やrangeのように）自動で定義されます。

サッとイテレータを使いたい時は、`for`文で集合からイテレータを作成することが良くあります。これは`.into_iter()`メソッドを呼び出しています。

    struct Fibonacci {
        curr: u32,
        next: u32,
    }

    // Implement `Iterator` for `Fibonacci`.
    // The `Iterator` trait only requires a method to be defined for the `next` element,
    // and an `associated type` to declare the return type of the iterator.
    impl Iterator for Fibonacci {
        // We can refer to this type using Self::Item
        type Item = u32;

        // ここではイテレーションの流れを`.curr`と`.next`を使用して定義しています。
        // 返り値の型は`Option<T>`で、これは：
        //     * `Iterator`が終了した時は`None`を返します。
        //     * そうでなければ`Some`でラップされた値を返します。
        fn next(&mut self) -> Option<Self::Item> {
            let current = self.curr;

            self.curr = self.next;
            self.next = current + self.next;

            // Since there's no endpoint to a Fibonacci sequence, the `Iterator`
            // will never return `None`, and `Some` is always returned.
            Some(current)
        }
    }

    // フィボナッチ数列のジェネレータを返します。
    fn fibonacci() -> Fibonacci {
        Fibonacci { curr: 0, next: 1 }
    }

    fn main() {
        // `0..3`は0, 1, 2をジェネレートする`Iterator`。
        let mut sequence = 0..3;

        println!("Four consecutive `next` calls on 0..3");
        println!("> {:?}", sequence.next());
        println!("> {:?}", sequence.next());
        println!("> {:?}", sequence.next());
        println!("> {:?}", sequence.next());

        // `for`は`None`を返すまで、イテレータを舐めていき、出てきた`Some`を
        // アンラップして変数（ここでは`i`）に束縛します。
        println!("Iterate through 0..3 using `for`");
        for i in 0..3 {
            println!("> {}", i);
        }

        // `take(n)`メソッドは`Iterator`を先頭から`n`番目の要素までに減らします。
        println!("The first four terms of the Fibonacci sequence are: ");
        for i in fibonacci().take(4) {
            println!("> {}", i);
        }

        // `skip(n)`メソッドは`Iterator`の先頭から`n`番目までの要素をとばします。
        println!("The next four terms of the Fibonacci sequence are: ");
        for i in fibonacci().skip(4).take(4) {
            println!("> {}", i);
        }

        let array = [1u32, 3, 3, 7];

        // `iter`メソッドは配列やスライスからイテレータを作成します。
        println!("Iterate the following array {:?}", &array);
        for i in array.iter() {
            println!("> {}", i);
        }
    }