Day 4:自訂迭代器
學習目標
- 實作 Iterator trait
- 理解 associated type
Item - 自己做出一個迭代器型別
今日重點
Iterator trait
pub trait Iterator {
type Item; // 產出元素的型別
fn next(&mut self) -> Option<Self::Item>; // 唯一必實作的方法
// 其他方法(map、filter 等)都是從 next 推導的預設實作
}
自訂迭代器
struct Counter {
count: u32,
max: u32,
}
impl Counter {
fn new(max: u32) -> Counter {
Counter { count: 0, max }
}
}
impl Iterator for Counter {
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
if self.count < self.max {
self.count += 1;
Some(self.count)
} else {
None
}
}
}
fn main() {
let counter = Counter::new(5);
let v: Vec<_> = counter.collect(); // [1, 2, 3, 4, 5]
println!("{:?}", v);
}
有了 Iterator,自動獲得一堆方法
一實作
next,就免費拿到.sum()、.map()、.filter()、.fold()、.collect()等眾多方法,因為它們都以next為基礎實作。
練習
struct Fibonacci {
a: u64,
b: u64,
}
impl Fibonacci {
fn new() -> Fibonacci { Fibonacci { a: 0, b: 1 } }
}
impl Iterator for Fibonacci {
type Item = u64;
fn next(&mut self) -> Option<Self::Item> {
let current = self.a;
let next = self.a + self.b;
self.a = self.b;
self.b = next;
Some(current) // 0, 1, 1, 2, 3, 5...
}
}
// 1. 用 take(10) 取前 10 個費式數
// 2. 用 sum() 加總前 10 個
自我檢查
- 理解 type Item 與 next()
- 能自訂迭代器型別
- 知道實作 Iterator 後會自動獲得大量方法
- 會用 take / skip 等適配器
深入連結
- The Book 第 13 章「Creating Your Own Iterators with the Iterator Trait」