我正在Rust中编写一个二叉搜索树,当我要从树中删除元素时,遇到了多个可变引用的问题。
代码如下:
use std::cmp;
use std::cmp::Ordering;
type Root<T> = Option<Box<Node<T>>>;
struct Node<T: cmp::Ord> {
data: T,
left: Root<T>,
right: Root<T>,
}
pub struct BinTree<T: cmp::Ord> {
size: i32,
root: Root<T>,
}
impl<T: cmp::Ord> BinTree<T> {
pub fn remove(&mut self, data: T) {
let mut curr = &mut self.root;
while let Some(ref mut node) = curr {
curr = match data.cmp(&node.data) {
Ordering::Less => &mut node.left,
Ordering::Greater => &mut node.right,
Ordering::Equal => break,
};
}
if let Some(_) = curr {
}
}
}
我得到了erorr说
error[E0503]: cannot use `*curr` because it was mutably borrowed
--> src/lib.rs:53:16
|
45 | while let Some(ref mut node) = curr {
| ------------ borrow of `curr.0` occurs here
...
53 | if let Some(_) = curr {
| ^^^^^^^
| |
| use of borrowed `curr.0`
| borrow later used here
error: aborting due to previous error
但是ref mut node
应该在while let
范围内才对吗?为什么在while let
块结束之后进行更多可变的引用会成为问题?
我只想做下面的事情,从这个二叉树中删除一个节点
if let Some(node) = curr {
match (node.left, node.right) {
(Some(_), Some(_)) => {
node.data = BinTree::pop_min_from(&mut node.left);
// get minimum data from left most node
// and drop that node by taking ownership of it
},
(Some(left), None) => {
curr.replace(left);
},
(None, Some(right)) => {
curr.replace(right);
},
(None, None) => {
curr.take();
},
}
self.size -= 1;
}
但是在这种情况下,我很容易获得所有权。我的大脑无法承受,甚至无法确保我在if let
中做正确的事情来处理目标节点。