我在用rust刷leetCode222题计算完全二叉树的节点数这个题目的时候遇到了一些问题
use std::cell::RefCell;
use std::rc::Rc;
impl Solution {
pub fn count_nodes(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
if root.is_none() {
return 0;
}
// let tree_node = root.unwrap().borrow(); // 这样写会编译报错,我不知道为什么会这样 ,但是可以从rustc --explain E0716 中获取提示
// 查阅资料之后大致意思是borrow()方法传入的参数是一个&self,连着写的 就是类似
// let tree_node = {
// let tmp = root.unwrap();
// borrow(&tmp) // <-- tmp is freed as we exit this block //返回的是一个悬垂引用
// }
// 但是我不明白为啥这么写是可以的 let tree_node = root.as_ref().unwrap().borrow();
// 但是可以这样写
//
// let tree_node = root.unwrap();
// let tree_node = tree_node.borrow();
let tree_node = root.as_ref().unwrap().borrow();
let left = Solution::count_level(tree_node.left.clone());
let right = Solution::count_level(tree_node.right.clone());
return if left == right {
Solution::count_nodes(tree_node.right.clone()) + (1 << left)
} else {
Solution::count_nodes(tree_node.left.clone()) + (1 << right)
};
}
fn count_level(node: Option<Rc<RefCell<TreeNode>>>) -> i32 {
let mut level: i32 = 0;
let mut cur = node;
while let Some(tree_node) = cur {
level += 1;
cur = tree_node.borrow().left.clone();
}
level
}
}
问题大致如我上面注释描述的 let tree_node = root.unwrap().borrow(); 会编译报错 而let tree_node = root.as_ref().unwrap().borrow();不会,为什么用了as_ref()之后可以打破这个规则呢? 顺便提一下,解题思路是抄的评论里某个大佬的思路,原链接 https://leetcode-cn.com/problems/count-complete-tree-nodes/solution/chang-gui-jie-fa-he-ji-bai-100de-javajie-fa-by-xia/ 其实用简单递归就可以解。
1
共 3 条评论, 1 页
评论区
写评论谢谢! 对以下内容的回复:
大概看了一下,我感觉是因为
let tree_node = root.unwrap().borrow();
这里,unwrap是pub fn unwrap(self) -> T
,返回是一个值,如果不保存就是临时值,之后的borrow会拿到临时值的引用。而
let tree_node = root.as_ref().unwrap().borrow();
,pub fn as_ref(&self) -> Option<&T>
,as_ref之后再unwrap出来的是一个引用,borrow拿到的是原值的引用,所以没有前面的问题。为啥没有大佬呢?