我有一个迭代器适配器链(我不知道编译时的数量)应用于初始迭代器。一个简单的例子是通过整除性过滤一个数字范围,并在末尾获得剩余数字的数量:
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());
字符串
现在,我想计数这个过滤器链的每个 * 阶段 * 中的元素的数量。
我的想法是在每个过滤器之间插入一个inspect
适配器,它为相应的 stage 增加一个计数器。然而,每个inspect
适配器都必须从循环外部的某个地方借用可变计数器。这导致了我在其中存储计数器的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]
。
有没有解决这个问题的方法,或者我必须使用不同于Vector的东西来存储这些计数器?也许有一种完全不同的方法来实现这一点?
Playground
2条答案
按热度按时间vsdwdz231#
不使用内部可变性,你可以通过迭代
filter_overview
来做到这一点。但是,你需要小心在iter_chain
之前声明它,否则它将在释放后使用:字符串
cwdobuhd2#
你可以使用内部可变性或原子来实现这一点。使用原子,向量变成
Arc<Vec<AtomicU64>>
(或者你选择的任何原子类型)。结果看起来像(Playground link):字符串
输出是
型