イテレーター
Iterator トレイトは、配列などのコレクションに対するイテレーターを実装するために使用されます。
このトレイトで定義が必要なのは、next 要素に対するメソッドだけです。 これは impl ブロック内で手動で定義することも、配列や範囲のように自動的に定義することもできます。
一般的な状況で便利に使えるように、for 構文は .into_iter() メソッドを使用して、一部のコレクションをイテレーターに変換します。
struct Fibonacci { curr: u32, next: u32, } // `Fibonacci` に対して `Iterator` を実装します。 // `Iterator` トレイトで必要なのは、`next` 要素に対して定義されたメソッドと、 // イテレーターの戻り値の型を宣言する `associated type` だけです。 impl Iterator for Fibonacci { // この型は Self::Item を使って参照できます type Item = u32; // ここでは、`.curr` と `.next` を使ってシーケンスを定義します。 // 戻り値の型は `Option<T>` です: // * `Iterator` が終了した場合、`None` が返されます。 // * それ以外の場合、次の値は `Some` に包まれて返されます。 // 戻り値の型で Self::Item を使用しているため、関数シグネチャを更新することなく // 型を変更できます。 fn next(&mut self) -> Option<Self::Item> { let current = self.curr; self.curr = self.next; self.next = current + self.next; // フィボナッチ数列には終端がないため、この `Iterator` は // 決して `None` を返さず、常に `Some` が返されます。 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` は `Iterator` が `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)` メソッドは、先頭の `n` 項を捨てることで `Iterator` を短くします。 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` メソッドは、配列/スライスに対する `Iterator` を生成します。 println!("Iterate the following array {:?}", &array); for i in array.iter() { println!("> {}", i); } }