如何写一个加倍迭代器的值?

时间:2017-11-19 14:40:44

标签: iterator rust

我想从基值1开始,然后将每次迭代的基值乘以2到定义的限制(比如我的数组的总长度)。

我是否必须实现一个特殊的迭代器才能做到这一点?或者我可以将其他迭代器方法(如mapfilter)组合在一起,以实现相同的功能。虽然我会想象实现我的迭代器会更有效率,但也更冗长。

2 个答案:

答案 0 :(得分:5)

您可以使用Iterator::scan

use std::iter;

fn main() {
    let items = iter::repeat(()).scan(1i32, |state, _| {
        let current_state = *state;
        *state = current_state * 2;
        Some(current_state)
    });

    println!("{:?}", items.take(10).collect::<Vec<_>>());
}

这是一个小的状态,从你的初始值(1i32)开始,每次都加倍状态,返回前一个状态。

由于闭包捕获了他们的环境,你可以在没有scan的情况下做到这一点,虽然我喜欢我的迭代器来包含他们需要的所有信息,所以我不太可能真的这样做:

let mut state = 1;
let items = iter::repeat(()).map(|_| {
    let v = state;
    state *= 2;
    v
});

总是长篇形式:

struct Doubling {
    value: i32,
}

impl Doubling {
    fn new(value: i32) -> Self {
        Self { value }
    }
}

impl Iterator for Doubling {
    type Item = i32;

    fn next(&mut self) -> Option<Self::Item> {
        let val = self.value;
        self.value *= 2;
        Some(val)
    }
}

fn main() {
    let items = Doubling::new(1);
    println!("{:?}", items.take(10).collect::<Vec<_>>());
}

答案 1 :(得分:2)

您可以执行以下操作:

rows, err := db.Query("DESCRIBE t_user")

输出:

fn main() {
    for i in (0..).map(|n| 2usize.pow(n)).take(10) { // take(10) so it stops
        println!("{}", i);
    }
}

效率很高,没有必要为此实现自己的迭代器。