我写了一个代码来解决树问题,Rc RefCell
用来包装树节点结构(实际上这部分是由 leetcode 提供的)。
我试图保存这棵树中每个节点的引用计数,但在模式匹配中,我不允许 match q[0].borrow().left.clone()
,因为它借用 q[0].borrow() 作为不可变的内联。
我最终得到了一个解决方法,但我无法解释它,并希望能看到针对这种情况的更好解决方案。
#[derive(Debug, PartialEq, Eq)]
pub struct TreeNode {
pub val: i32,
pub left: Option<Rc<RefCell<TreeNode>>>,
pub right: Option<Rc<RefCell<TreeNode>>>,
}
impl TreeNode {
#[inline]
pub fn new(val: i32) -> Self {
TreeNode {
val,
left: None,
right: None,
}
}
}
use std::cell::RefCell;
use std::rc::Rc;
struct Solution;
impl Solution {
pub fn foo(root: Option<Rc<RefCell<TreeNode>>>) {
let mut q: Vec<Rc<RefCell<TreeNode>>> = vec![];
if let Some(root_node) = root {
q.push(root_node);
// this line I borrow q[0] as immutable, but use it mutably in the next line
if let Some(left_node) = q[0].borrow().left.clone() {
q.push(left_node);
}
}
}
}
错误日志:
error[E0502]: cannot borrow `q` as mutable because it is also borrowed as immutable
--> main.rs:30:17
|
29 | if let Some(left_node) = q[0].borrow().left.clone() {
| -------------
| |
| immutable borrow occurs here
| a temporary with access to the immutable borrow is created here ...
30 | q.push(left_node);
| ^^^^^^^^^^^^^^^^^ mutable borrow occurs here
31 | }
| - ... and the immutable borrow might be used here, when that temporary is dropped and runs the destructor for type `Ref<'_, TreeNode>`
有什么优雅的方法可以实现与上述相同的语义吗?
我的解决方法是:
pub fn foo(root: Option<Rc<RefCell<TreeNode>>>) {
let mut q: Vec<Rc<RefCell<TreeNode>>> = vec![];
if let Some(root_node) = root {
q.push(root_node);
let q0_left = q[0].borrow().left.clone();
if let Some(left_node) = q0_left {
q.push(left_node);
}
}
}
我也不明白为什么这会避免borrow
问题。