Rust笔记 - IntoIterator trait

324 阅读1分钟

在Rust中,实现了IntoIterator trait 的类型是可迭代的类型,简单来说就是能够生成迭代器。下面是定义:

trait IntoIterator where Self::IntoIter::Item == Self::Item {
    type Item;
    type IntoIter: Iterator;
    fn into_iter(self) -> Self::IntoIter;
}

下面是实例代码:

use std::fmt::Debug;

#[derive(Debug, Clone, Copy)]
struct Counter {
    lower: u32,
    upper: u32,
    cur: u32,
}

impl Counter {
    fn new(lower: u32, upper: u32) -> Counter {
        Counter { lower, upper, cur: lower, }
    }
}

impl Iterator for Counter {
    type Item = u32;
    fn next(&mut self) -> Option<Self::Item> {
        self.cur += 1;

        if self.cur <= self.upper {
            Some(self.cur - 1)
        } else {
            self.cur = self.lower;
            None
        }
    }
}

struct Ranger {
    lower: u32,
    upper: u32,
}

impl Ranger {
    fn new(lower: u32, upper: u32) -> Ranger {
        Ranger {lower, upper,}
    }
}

impl IntoIterator for Ranger {
    type Item = u32;
    type IntoIter = Counter;
    fn into_iter(self) -> Self::IntoIter {
        Counter::new(self.lower, self.upper)
    }
}

fn main() {
    let cnt = Ranger::new(0, 5).into_iter();
    let v = cnt.filter(|x| *x % 2 == 0).collect::<Vec<u32>>();
    assert_eq!(vec![0, 2, 4], v);

    for (i, v) in cnt.enumerate() {
        assert_eq!(i as u32, v);
    }
}

在上面的例子中,Counter是迭代器,Ranger通过实现IntoIterator trait 生成一个Counter迭代器,通过迭代器对数据进行操作。