简体   繁体   English

如何实现无限 integer 迭代器?

[英]How to implement an infinite integer iterator?

I have created an iterator to generate an infinite list of integers from 0 onwards as shown below.我创建了一个迭代器来生成从 0 开始的无限整数列表,如下所示。

struct Infinite {
    current: i64,
}

impl Infinite {
    fn new() -> Infinite {
        Infinite { current: -1 }
    }
}

impl Iterator for Infinite {
    type Item = i64;

    fn next(&mut self) -> Option<Self::Item> {
        self.current += 1;
        Some(self.current)
    }
}

I hope to manipulate this list of integers with different commands such as Multiply (to multiple each integer by a number n) or subtract (to subtract n from each integer).我希望使用不同的命令来操作这个整数列表,例如乘法(将每个 integer 乘以一个数字 n)或减法(从每个整数中减去 n)。 Thus, I created a Multiply struct and implemented an iterator for it as shown below.因此,我创建了一个 Multiply 结构并为它实现了一个迭代器,如下所示。

struct Multiply {
    n: i64,
    inner: Box<dyn Iterator<Item = i64>>,
}

impl Multiply {
    fn new(inner: Box<dyn Iterator<Item = i64>>, n: i64) -> Multiply {
        Multiply { n, inner }
    }
}

impl Iterator for Multiply {
    type Item = i64;

    fn next(&mut self) -> Option<Self::Item> {
        Some(self.inner.next().unwrap() * self.n)
    }
}

However, I am not sure how to implement this in the main function.但是,我不确定如何在主 function 中实现这一点。 Should I begin by defining a new iter object this way?我应该以这种方式定义一个新的iter器 object 开始吗?

let mut iter = Infinite::new();
    iter.next();

Then, how should I implement the Multiply iterator to iter ?那么,我应该如何将 Multiply 迭代器实现到iter

fn main() {
    let mut iter = Multiply::new(Box::new(Infinite::new()), 2);

    println!("{}", iter.next().unwrap());
    println!("{}", iter.next().unwrap());
    println!("{}", iter.next().unwrap());
}
0
2
4

That said, it's pretty unusual for an iterator to carry a Box object.也就是说,迭代器携带Box object 是很不寻常的。 It's usually done with a generic.它通常使用泛型完成。 (Also, don't use .unwrap() when mapping from one iterator to another, use Option::map() instead to preserve the end of the iterator) (另外,从一个迭代器映射到另一个迭代器时不要使用.unwrap() ,而是使用Option::map()来保留迭代器的结尾)

struct Infinite {
    current: i64,
}

impl Infinite {
    fn new() -> Infinite {
        Infinite { current: -1 }
    }
}

impl Iterator for Infinite {
    type Item = i64;

    fn next(&mut self) -> Option<Self::Item> {
        self.current += 1;
        Some(self.current)
    }
}

struct Multiply<I> {
    n: i64,
    inner: I,
}

impl<I> Multiply<I> {
    fn new(inner: I, n: i64) -> Multiply<I> {
        Multiply { n, inner }
    }
}

impl<I> Iterator for Multiply<I>
where
    I: Iterator<Item = i64>,
{
    type Item = i64;

    fn next(&mut self) -> Option<Self::Item> {
        self.inner.next().map(|n| n * self.n)
    }
}

fn main() {
    let mut iter = Multiply::new(Infinite::new(), 2);

    println!("{}", iter.next().unwrap());
    println!("{}", iter.next().unwrap());
    println!("{}", iter.next().unwrap());
}
0
2
4

Further, this is usually done with an extension trait for Iterator so you are able to chain it.此外,这通常是通过Iterator的扩展特征来完成的,因此您可以将其链接起来。 This is also how the entire itertools crate works.这也是整个itertools crate 的工作方式。

struct Infinite {
    current: i64,
}

impl Infinite {
    fn new() -> Infinite {
        Infinite { current: -1 }
    }
}

impl Iterator for Infinite {
    type Item = i64;

    fn next(&mut self) -> Option<Self::Item> {
        self.current += 1;
        Some(self.current)
    }
}

struct Multiply<I>
where
    I: Iterator<Item = i64>,
{
    n: i64,
    inner: I,
}

impl<I> Iterator for Multiply<I>
where
    I: Iterator<Item = i64>,
{
    type Item = i64;

    fn next(&mut self) -> Option<Self::Item> {
        self.inner.next().map(|n| n * self.n)
    }
}

trait MultiplyExt
where
    Self: Iterator + Sized,
{
    fn multiply_with(self, n: i64) -> Multiply<Self>
    where
        Self: Iterator<Item = i64>,
    {
        Multiply { n, inner: self }
    }
}

impl<T: Iterator> MultiplyExt for T {}

fn main() {
    let mut iter = Infinite::new().multiply_with(2);

    println!("{}", iter.next().unwrap());
    println!("{}", iter.next().unwrap());
    println!("{}", iter.next().unwrap());
}
0
2
4

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM