Rust 如何就地删除集合类型的成员?
我想迭代结构中的集合类型并删除一些值,但生锈会阻止我销毁集合:Rust 如何就地删除集合类型的成员?,rust,Rust,我想迭代结构中的集合类型并删除一些值,但生锈会阻止我销毁集合: fn某些方法(&mut self){ self.collection=self 收集 .into_iter() .filter(/**/ .收集(); } 我可以克隆所有的值来构建另一个集合,但这并不高效。从Rust中的集合中删除值的惯用方法是什么?一个完整的示例(也包括到\u iter): 由于collection是一个BTreeMap,并且没有.drain()或.retain,并且您可以在处理过程中清空树,因此要做的事情是将树
fn某些方法(&mut self){
self.collection=self
收集
.into_iter()
.filter(/**/
.收集();
}
我可以克隆所有的值来构建另一个集合,但这并不高效。从Rust中的集合中删除值的惯用方法是什么?一个完整的示例(也包括到\u iter
):
由于
collection
是一个BTreeMap
,并且没有.drain()
或.retain
,并且您可以在处理过程中清空树,因此要做的事情是将树移出self.collection
,按照您的意愿操作它,然后将其放回
正如您所看到的,Rust不允许简单赋值,因为如果在代码段运行期间出现恐慌,self.collection
将处于不一致的状态。相反,您需要显式使用,这允许您通过提供替换来获得可变引用中内容的所有权对它进行修改,因此引用继续指向有效数据
fn some_method(&mut self) {
self.collection = std::mem::replace(&mut self.collection, BTreeMap::new())
.into_iter()
.filter(|_| true)
.collect();
}
如果
过滤器回调部分死机,那么self.collection
应该是什么?请提供一个更完整的示例片段,例如,iscollection
aVec
?如果是,那么。将(…)
而不是排入iter()
将在这里工作,因为它不拥有所有权。还有.retain(…)
@loganfsmyth在我的例子中,集合是一个BTreeMap
,它没有drain
方法。我真的需要关心恐慌吗?在rust中,恐慌是真正的恐慌,而不是应该正确处理的控制流?@loganfsmyth,我想要的是“在迭代时删除”,类似于iterator.remove()
在Java中。可能重复@JiamingLu Rust的迭代器可以迭代不可变的东西。Java的迭代器可以做到这一点吗?如果可以,删除
会做什么?在测试中打印一些东西而不是断言是一个好主意吗?不是真的,修复了这个问题!谢谢突出显示:)但是drain
只对Vec
有效,对于BTreeMap
或HashMap
@JiamingLu没有这样的方法,你的具体情况是什么?。这个答案对Vec来说似乎很方便。如果你将问题编辑得更具体,你可以得到更好、更具体的答案。filter\u-in\u-in\u-in\u-in\u-in\u-in\u-in\u-iter
在Vec
上不使用in\u-iter
;它只是在&mut-Vec
上使用进入iter
,这在非泛型上下文中很奇怪(您可以使用.iter\u-mut()
更具表达力和简洁性)。它还要求T
为Copy
。总的来说,这是一种奇怪的、不符合传统的行为。我不建议编写这样的代码。(不过,drain(…)
版本看起来不错。)
#[test]
fn score_test() {
let mut s = Scores::new();
s.collection.push(199);
s.collection.push(11);
s.filter_in_above_50();
assert_eq!(s.collection, vec![199]);
}
#[test]
fn score_test_using_into_iter() {
let mut s = Scores::new();
s.collection.push(199);
s.collection.push(11);
s.filter_in_above_50_using_into_iter();
assert_eq!(s.collection, vec![199]);
}
fn some_method(&mut self) {
self.collection = std::mem::replace(&mut self.collection, BTreeMap::new())
.into_iter()
.filter(|_| true)
.collect();
}