iterator - 如何在过滤器闭包中使用 Peekable 迭代器?

标签 iterator rust

我只需要找到下一个数字相同的数字:[1,2,2,3,4,4] 应该生成 [2,4]。因为我需要查看下一个数字,所以我想我会尝试使用 Peekable iterator并编写一个过滤器

fn main() {
    let xs = [1, 2, 2, 3, 4, 4];
    let mut iter = xs.iter().peekable();

    let pairs = iter.filter(move |num| {
        match iter.peek() {
            Some(next) => num == next,
            None       => false,
        }
    });

    for num in pairs {
        println!("{}", num);
    }
}

我得到一个错误:

error[E0382]: capture of moved value: `iter`
 --> src/main.rs:6:15
  |
5 |     let pairs = iter.filter(move |num| {
  |                 ---- value moved here
6 |         match iter.peek() {
  |               ^^^^ value captured here after move
  |
  = note: move occurs because `iter` has type `std::iter::Peekable<std::slice::Iter<'_, i32>>`, which does not implement the `Copy` trait

我认为这是因为闭包正在使用iter,但它没有借用它,它无法复制它。

我如何解决这个想在过滤器中引用迭代器的问题?

最佳答案

refer to the iterator inside a filter

我不相信你可以。当您调用 filter 时,它会取得基础迭代器的所有权:

fn filter<P>(self, predicate: P) -> Filter<Self, P> 
where
    P: FnMut(&Self::Item) -> bool, 

一旦你这样做了,它就消失了。没有更多的 iter。在一些类似的情况下,您可以使用 Iterator::by_ref可变地借用迭代器,驱动它一段时间,然后再引用原来的。这在这种情况下不起作用,因为内部迭代器需要第二次可变地借用它,这是不允许的。

find only the numbers where the next number is the same.

extern crate itertools;

use itertools::Itertools;

fn main() {
    let input = [1, 2, 2, 3, 4, 4];

    let pairs = input
        .iter()
        .tuple_windows()
        .filter_map(|(a, b)| if a == b { Some(a) } else { None });

    let result: Vec<_> = pairs.cloned().collect();
    assert_eq!(result, [2, 4]);
}

或者如果你想要只使用标准库的东西:

fn main() {
    let xs = [1, 2, 2, 3, 4, 4];

    let mut prev = None;
    let pairs = xs.iter().filter_map(move |curr| {
        let next = if prev == Some(curr) { Some(curr) } else { None };
        prev = Some(curr);
        next
    });

    let result: Vec<_> = pairs.cloned().collect();
    assert_eq!(result, [2, 4]);
}

关于iterator - 如何在过滤器闭包中使用 Peekable 迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47644485/

相关文章:

c++ - 如何在不暴露使用的容器的情况下暴露迭代器?

python - 创建一个 Python 生成器,从两个大列表中生成整数的有序乘积

rust - 将范围作为结构域

struct - 为什么要在结构中对引用使用相同的生命周期?

Rust,如何返回对结构中持续时间与结构一样长的内容的引用?

java - Java中LinkedList类的iterator()方法在哪里?

c++ - 在字符串中使用单词迭代器

rust - Iterator vs IntoIterator 用于扁平化

sorting - Lua 迭代按值排序的表

rust - 来自展开循环的可变借用冲突