借贷检查器在有条件地从二叉堆中弹出元素时感到不满。

5
我正在尝试编写一个简单的函数,该函数将弹出满足特定条件的二叉堆元素。该函数如下所示:

fn check_the_queue(mut queue: BinaryHeap<i32>) {
while !queue.is_empty() {
    let entry = queue.peek().unwrap();
    if *entry <= 0 {
        queue.pop();
    } 
}

当编译借用检查器开始报错时:

src/main.rs:52:13: 52:18 error: cannot borrow `queue` as mutable because it is also borrowed as immutable

我该如何解决这个问题,并让借用检查器满意?
1个回答

7
错误信息非常具体:
<anon>:8:13: 8:18 error: cannot borrow `queue` as mutable because it is also borrowed as immutable
<anon>:8             queue.pop();
                     ^~~~~
<anon>:5:21: 5:26 note: previous borrow of `queue` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `queue` until the borrow ends
<anon>:5         let entry = queue.peek().unwrap();
                             ^~~~~
<anon>:10:6: 10:6 note: previous borrow ends here
<anon>:4     while !queue.is_empty() {
...
<anon>:10     }
              ^

问题在于它使用了 "queue":
let entry = queue.peek().unwrap();

peek() 返回一个 Option<&T>,也就是一个具有指向类型为 T 的值的引用的选项。这个引用只在 entry 存活期间有效,即到函数结束为止。它指向存储在堆内存中的内容,因此它对堆进行了不可变借用。换句话说,只要 entry 存活(直到函数结束),堆就会被不可变地借用。

queue.pop() 对堆进行可变借用,因此在你执行此操作时,堆已经被不可变地借用,而你又试图对其进行可变借用。

借用检查规则指出,不能同时对同一对象进行可变和不可变的借用,因此你面临着问题。

为解决这个问题,找到避免同时进行两次借用的方法。例如,可以采取以下做法:

fn check_the_queue(mut queue: BinaryHeap<i32>) {
    while !queue.is_empty() {
        if *queue.peek().unwrap() <= 0 {
            queue.pop();
        } 
    }
}

也就是说,只需删除变量entry。这是因为在到达queue.pop()时,没有其他借用处于活动状态,且借用检查器已经满足 :)

生命周期和借用规则可能初学时难以理解,但随着时间的推移,陡峭的学习曲线会带来回报。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接