enum TreeNode {
Child(Rc<RefCell<[TreeNode]>>),
Leaf(i32),
Nil,
}
struct Tree {
root: TreeNode,
}
impl Tree {
fn new() -> Tree {
Tree {
root: TreeNode::Nil,
}
}
fn traverse(&mut self) {
let mut node = &self.root;
let mut parent = None;
while let TreeNode::Child(child) = node {
let mut child_mut = child.borrow_mut();
child_mut[1] = TreeNode::Leaf(1);
parent = Some(node);
node = &child_mut[0]; // error: borrowed value does not live long enough
}
}
}
编译错误
error[E0597]: `child_mut` does not live long enough
--> src/lib.rs:59:21
|
59 | node = &child_mut[0];
| ^^^^^^^^^ borrowed value does not live long enough
60 | }
| -
| |
| `child_mut` dropped here while still borrowed
| borrow might be used here, when `child_mut` is dropped and runs the destructor for type `std::cell::RefMut<'_, [TreeNode]>`
我知道错误原因,因为child_mut
是while
范围内的临时变量,所以rust不允许将其引用分配给node
,但我不知道如何修复它。帮助需要。
Rc
与RefCell
是相当棘手的。您必须相当自由地使用Rc::clone
,以便拥有值而不是引用,因为引用不会存在足够长的时间。一般的经验法则:如果你有一个&T
不能存活足够长的时间,你应该想办法把它改成&Rc<T>
或&Rc<RefCell<T>>
,这样你就可以把它改成Rc::clone
来拥有它。
这应该可以工作(至少,它编译并且看起来是正确的):
fn traverse(&mut self) {
if let TreeNode::Child(root) = &self.root {
let mut node = Rc::clone(root);
let mut parent = None;
while let TreeNode::Child(child) = &Rc::clone(&node).borrow()[1] {
let child = Rc::clone(child);
child.borrow_mut()[1] = TreeNode::Leaf(1);
parent = Some(node);
node = child;
}
}
}