当有条件地从二进制堆中弹出元素时,借用检查器不高兴

Dmi*_*rov 5 rust

我正在尝试编写一个简单的函数,它会从BinaryHeap中弹出满足某个条件的元素.该函数如下所示:

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

编译借阅检查程序时开始抱怨:

src/main.rs:52:13: 52:18 error: cannot borrow `queue` as mutable because it is also borrowed as immutable
Run Code Online (Sandbox Code Playgroud)

我怎样才能解决这个问题并使借阅检查员满意?

Fil*_*ves 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     }
              ^
Run Code Online (Sandbox Code Playgroud)

问题是这借了queue:

let entry = queue.peek().unwrap();
Run Code Online (Sandbox Code Playgroud)

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();
        } 
    }
}
Run Code Online (Sandbox Code Playgroud)

也就是说,只需删除变量即可entry.这是有效的,因为当你到达时queue.pop(),没有其他借用活跃,借用检查员很高兴:)

生命周期和借阅规则起初可能很难理解,但陡峭的学习曲线会随着时间推移而得到回报.