如何在Rust中编写自己的可链接迭代器函数?

如何在Rust中编写自己的可链接迭代器函数?,rust,iterator,Rust,Iterator,假设我想在一个数字迭代器中将每个值加倍。我可以这样做: 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| pri

假设我想在一个数字迭代器中将每个值加倍。我可以这样做:

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?我想我必须为迭代器创建一个接口并实现它?有很多类型需要正确处理,因此对于这个愚蠢的示例,一个有效的解决方案会很有帮助。

首先,您必须创建一个新类型来实现迭代器。最简单的方法是包装您要针对的类型的迭代器:

struct Double<T: ?Sized> {
    inner: T,
}
就这样!您只需要添加一个双构造函数。最符合人体工程学的解决方案是扩展迭代器。大概是这样的:

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 }
    }
}

了解这一点的最佳方法是在源代码中查找任何内置迭代器函数。例如,这是一个简单的例子。结构的实现是。请注意,这个实现覆盖了很多方法,但您只需要定义next。这是一个值得学习的好东西,但我认为在这种特殊情况下,这并不干净。它将引入许多代码,与仅按预期使用map相比,这些代码并不是真正必要的。@E4\u net\u或类似的东西\u感谢链接。我同意,在这个简单的例子中,它并不干净,但我需要一个简单的例子,这样就不会使问题变得过于笼统。请不要回答重复的问题;这使得维护最新的知识库变得更加困难。
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 }
    }
}
fn main() {
    vec![1, 2, 3]
        .into_iter()
        .into_double()
        .for_each(|x| println!("{}", x));
}