< 返回版块

Zhanghailin1995 发表于 2020-05-09 09:11

Tags:rust,leetcode

我在用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/ 其实用简单递归就可以解。

评论区

写评论
作者 Zhanghailin1995 2020-05-10 12:59

谢谢! 对以下内容的回复:

whfuyn 2020-05-09 17:45

大概看了一下,我感觉是因为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拿到的是原值的引用,所以没有前面的问题。

作者 Zhanghailin1995 2020-05-09 15:40

为啥没有大佬呢?

1 共 3 条评论, 1 页