LeetCode翻转二叉树:为何此处需要显式类型注解?
显式指定类型解决RefCell可变借用编译错误的原因
先看你提供的代码:
use std::rc::Rc; use std::cell::RefCell; impl Solution { pub fn invert_tree(root: Option<Rc<RefCell<TreeNode>>>) -> Option<Rc<RefCell<TreeNode>>> { let mut stack: Vec<Option<Rc<RefCell<TreeNode>>>> = vec![root.clone()]; while stack.len() > 0 { if let Some(node) = stack.pop().unwrap() { let n: &mut TreeNode = &mut node.borrow_mut(); std::mem::swap(&mut n.left, &mut n.right); stack.extend(vec![n.left.clone(), n.right.clone()]); } } root } }
当你把let n: &mut TreeNode改为let n = &mut node.borrow_mut()时,编译器会推断n的类型是&mut RefMut<TreeNode>,这会触发编译错误,原因如下:
RefCell::borrow_mut()返回的是RefMut<TreeNode>,它是一个用来在运行时保证RefCell借用规则的智能指针。- 当你使用
&mut n.left和&mut n.right时,需要先对n(&mut RefMut<TreeNode>)解引用得到RefMut<TreeNode>,再访问字段。但RefMut的解引用会维持对RefCell的可变借用状态,编译器会认为你同时对*n(即RefMut<TreeNode>)进行了两次可变借用,违反了Rust的借用规则,因此报错。
而显式指定n的类型为&mut TreeNode时,会触发强制类型转换:
- 因为
RefMut<T>实现了DerefMut<Target = T>,编译器会自动将&mut RefMut<TreeNode>强制转换成&mut TreeNode,直接拿到内部TreeNode的可变引用。 - 此时
n是指向TreeNode的直接可变引用,访问n.left和n.right属于对同一个结构体的不同字段进行可变借用,Rust允许这种操作(只要字段不重叠),因此代码可以正常编译。
内容的提问来源于stack exchange,提问作者maxspiri
相关产品推荐
相关产品推荐

