Info
This post is auto-generated from RSS feed The Rust Programming Language Forum - Latest topics. Source: A BorrowMutError report when use a different Argument
I wrote a Double-end linked list, "already borrowed: BorrowMutError" Error reported when call the delete method with "&head.borrow().next.as_ref().unwrap() " but works ok with argument "&head".
I spent hours unable to figure out why is that ? Please help. thank you.
struct Node<T> {
value: T,
next: Option<Rc<RefCell<Node<T>>>>,
prev: Option<Rc<RefCell<Node<T>>>>,
}
impl<T> Node<T> {
fn new(value: T) -> Self {
Self { value, next: None, prev: None }
}
}
fn delete<T>(node: &Rc<RefCell<Node<T>>>) {
let prev_node = node.borrow().prev.clone();
let next_node = node.borrow().next.clone();
node.borrow_mut().prev = None;
node.borrow_mut().next = None;
if let Some(ref prev) = prev_node{
// Error: already borrowed: BorrowMutError report here when
// call the delete method with argument: &head.borrow().next.as_ref().unwrap()
// but works ok with argument: &head
prev.borrow_mut().next = next_node.clone();
}
if let Some(next) = next_node {
next.borrow_mut().prev = prev_node;
}
}
fn insert_after<T>(node: &Rc<RefCell<Node<T>>>, value: T) {
let new_node = Rc::new(RefCell::new(Node::new(value)));
let next_node = node.borrow().next.clone();
node.borrow_mut().next = Some(new_node.clone());
new_node.borrow_mut().prev = Some(node.clone());
if let Some(next) = next_node {
new_node.borrow_mut().next = Some(next.clone());
next.borrow_mut().prev = Some(new_node);
}
}
fn insert_before<T>(node: &Rc<RefCell<Node<T>>>, value: T) {
let new_node = Rc::new(RefCell::new(Node::new(value)));
let prev_node = node.borrow().prev.clone();
node.borrow_mut().prev = Some(new_node.clone());
new_node.borrow_mut().next = Some(node.clone());
if let Some(prev) = prev_node {
new_node.borrow_mut().prev = Some(prev.clone());
prev.borrow_mut().next = Some(new_node);
}
}
fn traverse_forward<T: std::fmt::Debug>(start: &Rc<RefCell<Node<T>>>) {
let mut current = Some(start.clone());
while let Some(node) = current {
print!("{:?} ", node.borrow().value);
current = node.borrow().next.clone();
}
println!();
}
fn traverse_backward<T: std::fmt::Debug>(end: &Rc<RefCell<Node<T>>>) {
let mut current = Some(end.clone());
while let Some(node) = current {
print!("{:?} ", node.borrow().value);
current = node.borrow().prev.clone();
}
println!();
}
here is the unit test:
#[test]
fn test_create(){
let head = Rc::new(RefCell::new(Node::new(1)));
insert_after(&head, 2);
insert_after(&head.borrow().next.as_ref().unwrap(), 3);
insert_before(&head, 0);
println!("Traverse forward:");
traverse_forward(&head.borrow().prev.as_ref().unwrap().clone());
let tail = head.borrow().next.as_ref().unwrap().borrow().next.as_ref().unwrap().clone();
println!("Traverse backward:");
traverse_backward(&tail);
println!("After deleting node with value 2:");
// call with '&head.borrow().next.as_ref().unwrap()' reports Error: already borrowed: BorrowMutError
// call with "&head" works ok.
delete(&head.borrow().next.as_ref().unwrap());
traverse_forward(&head.borrow().prev.as_ref().unwrap().clone());
}
3 posts - 2 participants
🏷️ Rust_feed