Rust 获取BTreeSet的第一个成员
在Rust中,我有一个Rust 获取BTreeSet的第一个成员,rust,set,Rust,Set,在Rust中,我有一个b树集,用来保持我的值有序。我有一个循环,它应该检索并删除集合中的第一个(最低)成员。我正在使用克隆迭代器检索第一个成员。代码如下: use std::collections::BTreeSet; fn main() { let mut start_nodes = BTreeSet::new(); // add items to the set while !start_nodes.is_empty() { let mut st
b树集
,用来保持我的值有序。我有一个循环,它应该检索并删除集合中的第一个(最低)成员。我正在使用克隆迭代器检索第一个成员。代码如下:
use std::collections::BTreeSet;
fn main() {
let mut start_nodes = BTreeSet::new();
// add items to the set
while !start_nodes.is_empty() {
let mut start_iter = start_nodes.iter();
let mut start_iter_cloned = start_iter.cloned();
let n = start_iter_cloned.next().unwrap();
start_nodes.remove(&n);
}
}
但是,这给了我以下编译错误:
error[E0502]:无法将'start_nodes'借用为可变的,因为它也被借用为不可变的
-->进度rs:60:6
|
56 |让mut start_iter=start_nodes.iter();
|--------此处发生不可变借用
...
60 |启动_节点。删除(&n);
|^^^^^^^^^^^^^^^此处发生可变借用
...
77 | }
|-不可变的借阅到此结束
为什么start\u nodes.iter()
被认为是不可变的借用?我应该采取什么方法来获得第一个成员
我正在使用版本
1.14.0
(不是选择)。不确定这是最佳方法,但我通过引入一个新的作用域来修复它,以确保可变借用在可变借用发生之前结束:
use std::collections::BTreeSet;
fn main() {
let mut start_nodes = BTreeSet::new();
// add items to the set
while !start_nodes.is_empty() {
let mut n = 0;
{
let mut start_iter = start_nodes.iter();
let mut start_iter_cloned = start_iter.cloned();
let x = &mut n;
*x = start_iter_cloned.next().unwrap();
}
start_nodes.remove(&n);
}
}
为什么start\u nodes.iter()
被认为是不可变的借用
无论何时提出这样的问题,都需要查看函数的原型,在本例中是BTreeSet::iter()的原型
iter()的定义中未明确提及寿命'a
;但是,生存期省略规则使函数定义等效于
fn iter<'a>(&'a self) -> Iter<'a, T>
然而,请注意,这段代码是不必要的冗长。您创建的新迭代器及其克隆版本只存在于新范围内,并且它们实际上没有用于任何其他目的,因此您也可以编写
while !start_nodes.is_empty() {
let n = start_nodes.iter().next().unwrap().clone();
start_nodes.remove(&n);
}
它的作用完全相同,并通过避免将中间值存储在变量中来避免长寿借款的问题,以确保它们的生存期在表达式之后立即结束
最后,虽然您没有给出用例的全部细节,但我强烈怀疑您最好使用BinaryHeap
而不是BTreeSet
:
use std::collections::BinaryHeap;
fn main() {
let mut start_nodes = BinaryHeap::new();
start_nodes.push(42);
while let Some(n) = start_nodes.pop() {
// Do something with `n`
}
}
此代码更短、更简单,完全避免了借用检查器的问题,而且效率更高。您的Rust 2018示例(使用NLL)。@LukasKalbertodt谢谢,您是对的。不幸的是,使用最新的编译器对我来说不是一个解决方案,因为这是一个uni评估,标记环境使用Rust 1.14.0。然而,如果我知道我不是在做傻事,而是出于兴趣,我应该能够让它工作起来:什么大学?总是感兴趣的是在哪里教生锈。@卢卡斯卡尔伯托特肯特大学。“不过,这可能会让你失望,因为这只是一个研究各种语言的模块,所以生锈的报道相当肤浅。”Stargateur道歉,编辑。我发布的时候没有意识到编译器不是最新版本。
while !start_nodes.is_empty() {
let n = {
let mut start_iter = start_nodes.iter();
let mut start_iter_cloned = start_iter.cloned();
start_iter_cloned.next().unwrap()
};
start_nodes.remove(&n);
}
while !start_nodes.is_empty() {
let n = start_nodes.iter().next().unwrap().clone();
start_nodes.remove(&n);
}
use std::collections::BinaryHeap;
fn main() {
let mut start_nodes = BinaryHeap::new();
start_nodes.push(42);
while let Some(n) = start_nodes.pop() {
// Do something with `n`
}
}