假设我想将数字迭代器中的每个值加倍。我可以这样做:
vec![1, 2, 3]
.into_iter()
.map(|x| x * 2)
.for_each(|x| println!("{}", x)); //Prints 2, 4, 6.
为了获得更简洁的代码,我更愿意这样做:
vec![1, 2, 3]
.into_iter()
.double() //I need to implement this.
.for_each(|x| println!("{}", x));
如何编写自己的可链接迭代器函数,如本例中的 double
?我想我必须创建一个接口(interface)并为 Iterator 实现它?有很多类型需要正确处理,因此针对这个愚蠢示例的可行解决方案会很有帮助。
首先,您必须创建一个新类型来实现您的迭代器。最简单的方法是包装一个你想要定位的类型的迭代器:
struct Double<T: ?Sized> {
inner: T,
}
现在,如果内部类型 T
是正确的类型,您只需为该类型实现 Iterator
特性。像这样的东西:
impl<T> Iterator for Double<T>
where T: Iterator<Item = i32> {
type Item = i32;
fn next(&mut self) -> Option<i32> {
self.inner.next().map(|x| 2*x)
}
}
就是这样!您只需要添加一个 Double
构造函数。最符合人体工程学的解决方案是扩展 Iterator
。像这样:
trait Doubler : Iterator<Item = i32> {
fn into_double(self) -> Double<Self>;
}
impl<T> Doubler for T
where T: Iterator<Item = i32> {
fn into_double(self) -> Double<Self> {
Double { inner: self }
}
}
用法示例(playground):
fn main() {
vec![1, 2, 3]
.into_iter()
.into_double()
.for_each(|x| println!("{}", x));
}