- 此问题在此处已有答案**:
How to handle "temporary value dropped" error when adapting Box-based tree structure to Rc+RefCell?(2个答案)
昨天关门了。
我在关注另一个帖子:Understanding Rust Rc<RefCell<_>>
其中op尝试使用Box实现树,并成功实现了该树,但随后尝试使用Rc和RefCell实现该树,但发现了问题。接受的答案可以编译,但无法运行,因为它不向根添加节点。我尝试稍微更新接受的答案,以使其运行,但无法运行。基本上,我尝试在循环中获取可变引用,但无法'因为我借用了一个不可变的引用,但是如果我得到的borrow_mut()是一个私有字段,那么我假设如果它是一个可变的引用,我不能访问它所包含的值的任何属性?
我该怎么做才能让这段代码正常工作?
use std::borrow::BorrowMut;
use std::cell::RefCell;
use std::cmp::Ordering;
use std::rc::Rc;
use std::fmt;
#[derive(Debug, Clone)]
pub(crate) struct TreeBox<T> {
root: Option<Box<NodeBox<T>>>,
}
#[derive(Debug, Clone)]
struct NodeBox<T> {
value: T,
left: Option<Box<NodeBox<T>>>,
right: Option<Box<NodeBox<T>>>,
}
impl<T: Ord> TreeBox<T> {
fn new() -> Self {
Self { root: None }
}
pub fn insert(&mut self, value: T) -> bool {
let mut node = &mut self.root;
while let Option::Some(current_node) = node {
match current_node.value.cmp(&value) {
Ordering::Less => node = &mut current_node.right,
Ordering::Equal => return false,
Ordering::Greater => node = &mut current_node.left,
}
}
*node = Option::Some(Box::new(NodeBox {
value,
left: Option::None,
right: Option::None,
}));
return true;
}
}
#[derive(Debug, Clone)]
pub(crate) struct Tree<T> {
root: Option<Rc<RefCell<Node<T>>>>,
}
#[derive(Debug, Clone, PartialEq)]
struct Node<T> {
value: T,
left: Option<Rc<RefCell<Node<T>>>>,
right: Option<Rc<RefCell<Node<T>>>>,
}
impl<T: Ord + fmt::Debug> Tree<T> {
fn new() -> Self {
Self { root: None }
}
pub fn insert(&mut self, value: T) -> bool {
let mut node = &mut self.root;
while let Some(current_node) = node {
let current_node = current_node.borrow();
let cmp = current_node.value.cmp(&value);
let new_node = match cmp {
Ordering::Less => &mut current_node.left,
Ordering::Equal => return false,
Ordering::Greater => &mut current_node.right,
};
node = new_node;
}
// let mut node = &mut node;
*node = Some(Rc::new(RefCell::new(Node {
value,
left: None,
right: None,
})));
println!("node: {:?}", node);
true
}
}
fn main() {
let mut tree_box = TreeBox::new();
tree_box.insert(1);
tree_box.insert(2);
tree_box.insert(3);
let mut tree = Tree::new();
tree.insert(1);
tree.insert(2);
tree.insert(3);
println!("TreeBox: {:?}", tree_box);
println!("Tree: {:?}", tree);
}
1条答案
按热度按时间sauutmhj1#
接受的答案会进行编译,但不起作用,因为它不会向根添加节点。
你是正确的,并修复原来的解决方案,这里的版本,添加根节点正确:
基本上,我试图在循环中获得可变引用,但我做不到,因为我借用了一个不可变引用。
问题是稍有不同的,你不能遍历这个
Rc<RefCell>
树,至少不能像这样交互,因为当你使用它的时候,你的实现需要保留“borrow”,并且在每个循环之后释放“borrow”。但是如果我得到的borrow_mut()值是私有字段,那么如果它是一个可变引用,我就不能访问它所包含的值的任何属性?
不完全是这样,这里发生的是你调用的函数
RefCell::borrow_mut
不是返回一个RefMut<Node>
,你实际上调用的是返回&mut RefMut<...>
的<Rc as BorrowMut>::borrow_mut
,通过访问value
你试图从RefCell
访问私有字段value
,而不是Node
。注意,在我的实现中,我显式地调用了
RefCell::borrow_mut
,这解决了这个问题。