我想迭代一个
Vec
对其中的对象执行各种操作(这比 usize
更复杂),并且,如果收到停止迭代的命令,则仅保留那些没有的对象尚未处理。
fn main() {
let _ = iterate();
}
fn iterate(){
let mut objs_for_processing = Vec::new();
for i in 0..10 {
objs_for_processing.push(i);
}
let mut n = 0;
objs_for_processing.retain(|obj| {
n += 1;
if n > 3 {
println!("STOP iteration!...");
return true // i.e. retain
}
println!("iteration, do some business with obj {}", obj);
false
});
println!("objs_for_processing.len() {} {:#?}", objs_for_processing.len(), objs_for_processing);
}
上面的问题很明显,是你必须完成所有迭代,即使你知道你想要保留所有其他元素......
我找到了这个问题和这个问题。后者“似乎”更有希望。但事实证明,您无法更改 retain
闭包的返回类型(即接受
Result
,因此您可以返回 Err
,这将停止迭代),据我所知可以告诉。我找到的唯一解决方案是克隆 Vec
,使用普通的
for ... in
进行迭代,然后在处理时从克隆(称为 depleted_vec
)中删除项目,使用相当麻烦的let index = depleted_vec.iter().position(|x| x == obj).unwrap();
depleted_vec.remove(index);
...然后将
objs_for_processing
分配给
depleted_vec
。至少这样我可以使用 break
来停止迭代。这似乎是一件相当合理的事情:难道没有一些更优雅的方法来做到这一点吗?
NB 我还想知道是否可能存在基于
Iterator
的解决方案,因此我尝试使用
iter().filter(...).collect()
...这会产生 Vec
的 &usize
,而不是 usize
。因此它也许可以使用,但需要额外的处理成本。不漂亮:只是感觉应该有更好的东西。Vec
,您只需使用索引进行迭代并删除元素即可:
let mut i = 0;
let mut n = 0;
while i < objs_for_processing.len() {
if n > 3 {
println!("STOP iteration!...");
break;
}
if true {
let obj = &objs_for_processing[i];
println!("iteration, do some business with obj {}", obj);
objs_for_processing.remove(i);
// Don't increment `i`!
} else {
i += 1;
}
n += 1;
}
这不会像
retain()
那么有效(因为它可以批量删除),但这对你来说可能并不重要。