调用Iterator :: take后有没有办法耗尽迭代器?

时间:2018-06-18 15:57:19

标签: iterator rust

我有一个迭代器,我想使用大小为w的滑动窗口进行分析。我尝试将迭代器中的第一个w项移动到数据结构中,并希望遍历其余项。但是,当我使用numbers.take(w)时,我失去了迭代器的所有权,并且无​​法使用剩余的项目:

use std::collections::VecDeque;

pub fn analysis<I>(numbers: I, w: usize)
where
    I: Iterator<Item = u64>,
{
    let mut window = VecDeque::with_capacity(w);
    for number in numbers.take(w) {
        window.push_back(number);
    }

    for (i, number) in numbers.enumerate() {
        // do some analysis
    }
}
error[E0382]: use of moved value: `numbers`
  --> src/main.rs:12:24
   |
8  |     for number in numbers.take(w) {
   |                   ------- value moved here
...
12 |     for (i, number) in numbers.enumerate() {
   |                        ^^^^^^^ value used here after move
   |
   = note: move occurs because `numbers` has type `I`, which does not implement the `Copy` trait

我使用tee包中的itertools函数找到了解决方法:

extern crate itertools;

use itertools::Itertools;
use std::collections::VecDeque;

pub fn analysis<I>(numbers: I, w: usize)
where
    I: Iterator<Item = u64>,
{
    let mut window = VecDeque::with_capacity(w);
    let (first_numbers, numbers) = numbers.tee();

    for number in first_numbers.take(w) {
        window.push_back(number);
    }

    for number in numbers.skip(w) {
        window.pop_front();
        window.push_back(number);
        // do stuff
    }
}

然而,这让我觉得有点笨拙。有没有办法在不克隆或复制迭代器的情况下解决这个问题?换句话说:有没有办法将迭代器拆分成两个可以独立使用的段?

0 个答案:

没有答案