我有一个迭代器适配器链(我不知道编译时有多少)应用于初始迭代器. 一个简化的示例是,根据数字的整除性筛选一系列数字,并获得末尾剩余数字的数量:

    let n: usize = 10;
    let mut iter_chain: Box<dyn std::iter::Iterator<Item = usize>> = Box::new(1..=n);

    for i in 2..n {
        iter_chain = Box::new(iter_chain.filter(move |j| j % i != 0));
    }

    println!("{}", iter_chain.count());

现在,我希望在这个过滤器链的每个stage个中都有count the numbers of elements个.

我的 idea 是在每个过滤器之间插入一个inspect适配器,增加对应stage的计数器. 但是,每个inspect适配器必须从循环外部的某个地方borrow 可变计数器. 这导致了对Vector的多次相互borrow ,此时我将计数器存储在Vector中.

    let n: usize = 10;
    let mut iter_chain: Box<dyn std::iter::Iterator<Item = usize>> = Box::new(1..=n);

    let mut filter_overview = vec![0; n];
    for i in 2..n {
        // cannot borrow `filter_overview` as mutable more than once at a time
        //                                                   |
        //                                                   V
        iter_chain = Box::new(iter_chain.inspect(|_| filter_overview[i] += 1)); 
        iter_chain = Box::new(iter_chain.filter(move |j| j % i != 0));
    }

    println!("{filter_overview:?} {}", iter_chain.count());

本例中filter_overview的预期值为[10, 5, 3, 3, 2, 2, 1, 1].

是否有解决此问题的方法,或者我是否必须使用不同于向量的其他方法来存储这些计数器? 也许有一种完全不同的方式来实现这一点?

Playground

推荐答案

您可以通过迭代超过filter_overview次来实现,而不是使用内部可变性.但是,您需要注意在iter_chain之前声明它,否则它将在释放后使用:

let n: usize = 10;
let mut filter_overview = vec![0; n];
let mut iter_chain: Box<dyn std::iter::Iterator<Item = usize>> = Box::new(1..=n);

for (i, overview) in std::iter::zip(2..n, &mut filter_overview) {
    iter_chain = Box::new(
        iter_chain
            .inspect(|_| *overview += 1)
            .filter(move |j| j % i != 0),
    );
}

println!("{filter_overview:?} {}", iter_chain.count());

Rust相关问答推荐

PyReadonlyArray2到Vec T<>

在Rust中,有没有一种方法让我定义两个 struct ,其中两个都遵循标准 struct ?

带扫描的铁 rust 使用滤镜

在跨平台应用程序中使用std::OS::Linux和std::OS::Windows

一种随机局部搜索算法的基准(分数)

为什么TcpListener的文件描述符和生成的TcpStream不同?

习语选项<;T>;到选项<;U>;当T->;U用From定义

从管道读取后重置标准输入

如何从borrow 的异步代码运行阻塞代码?

无法将`&Vec>`转换为`&[&str]`

为什么带有生命周期指定的方法不能被调用两次?

Rust 程序中的内存泄漏

Rust 中 Mutex<> 的深拷贝?

如何递归传递闭包作为参数?

如何刷新 TcpStream

为什么 for_each 在释放模式(cargo run -r)下比 for 循环快得多?

我如何将 google_gmail1::Gmail> 传递给线程生成?

Rust:如果我知道只有一个实例,那么将可变borrow 转换为指针并返回(以安抚borrow 判断器)是否安全?

如何在 Rust 中构建一个 str

为什么可以从不可变 struct 的字段中移动?