我的代码看起来像这样:
struct Bar {
i: i32,
}
struct Foo {
v: Vec<Bar>,
}
impl Foo {
fn foo(&mut self) {
self.v.drain(self.v.iter().filter(|b| b.i < 10));
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,Bar不允许复制或克隆.
我想删除所有Bar不满足该条件的s.最初我以为我可以迭代它们并调用remove但是我不允许有两个可变借用或一个可变借用,如果存在一个完全有意义的不可变借用.
我想最简单的事情是只clone,filter和collect,但我不能克隆或复制.
我该怎么做?
如果你查看界面Vec,你将找不到基于谓词擦除某些元素的方法.相反,你会发现retain它保持基于谓词的元素.
当然,两者都是对称的,retain如果你通过"删除"或"擦除"过滤方法名称,它就更难找到(它的描述中确实包含"删除").
提供的示例说明了一切:
let mut vec = vec![1, 2, 3, 4];
vec.retain(|&x| x % 2 == 0);
assert_eq!(vec, [2, 4]);
Run Code Online (Sandbox Code Playgroud)
在每晚的Rust中,您可以使用Vec::drain_filter:
#![feature(drain_filter)]
#[derive(Debug)]
struct Bar {
i: i32,
}
fn main() {
let mut bars = vec![Bar { i: 1 }, Bar { i: 10 }, Bar { i: 3 }, Bar { i: 100 }];
bars.drain_filter(|b| b.i < 10);
println!("{:?}", bars);
}
Run Code Online (Sandbox Code Playgroud)
有趣的drain_filter是,您可以获取被拒绝的值,因为它返回了它们的迭代器:
let rejects: Vec<_> = bars.drain_filter(|b| b.i < 10).collect();
Run Code Online (Sandbox Code Playgroud)
您还可以选择修改要迭代的值:
bars.drain_filter(|b| {
b.i -= 1;
b.i < 10
});
Run Code Online (Sandbox Code Playgroud)