从 Option>> 解开并访问 T

2023-11-27

我正在尝试用 Rust 解决一些 Leetcode 问题。然而,我在使用 LeetCode 时遇到了一些困难TreeNode执行。

use std::cell::RefCell;
use std::rc::Rc;

// TreeNode data structure
#[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,
        }
    }
}

如果我想做一个中序遍历,如何解开TreeNode's Option<Rc<RefCell<TreeNode>>>对象,访问其.val .left .right并将它们作为输入传递给递归函数?

我努力了:

pub struct Solution;

impl Solution {
    pub fn inorder_traversal(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
        let mut ret: Vec<i32> = vec![];
        match root {
            Some(V) => Solution::helper(&Some(V), &mut ret),
            None => (),
        }

        ret
    }

    fn helper(node: &Option<Rc<RefCell<TreeNode>>>, ret: &mut Vec<i32>) {
        match node {
            None => return,
            Some(V) => {
                // go to the left branch
                Solution::helper(
                    (*Rc::try_unwrap(Rc::clone(V)).unwrap_err())
                        .into_inner()
                        .left,
                    ret,
                );
                // push root value on the vector
                ret.push(Rc::try_unwrap(Rc::clone(V)).unwrap_err().into_inner().val);
                // go right branch
                Solution::helper(
                    (*Rc::try_unwrap(Rc::clone(V)).unwrap_err())
                        .into_inner()
                        .right,
                    ret,
                );
            }
        }
    }
}

fn main() {}

(操场)

编译器抱怨:

error[E0308]: mismatched types
  --> src/lib.rs:42:21
   |
42 | /                     (*Rc::try_unwrap(Rc::clone(V)).unwrap_err())
43 | |                         .into_inner()
44 | |                         .left,
   | |_____________________________^ expected reference, found enum `std::option::Option`
   |
   = note: expected type `&std::option::Option<std::rc::Rc<std::cell::RefCell<TreeNode>>>`
              found type `std::option::Option<std::rc::Rc<std::cell::RefCell<TreeNode>>>`
help: consider borrowing here
   |
42 |                     &(*Rc::try_unwrap(Rc::clone(V)).unwrap_err())
43 |                         .into_inner()
44 |                         .left,
   |

但如果我尝试这个建议,它也会抱怨:

error[E0507]: cannot move out of an `Rc`
  --> src/lib.rs:42:22
   |
42 |                     &(*Rc::try_unwrap(Rc::clone(V)).unwrap_err())
   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of an `Rc`

error[E0507]: cannot move out of data in a `&` reference
  --> src/lib.rs:42:22
   |
42 |                     &(*Rc::try_unwrap(Rc::clone(V)).unwrap_err())
   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |                      |
   |                      cannot move out of data in a `&` reference
   |                      cannot move

Unwrap和访问T从一个Option<Rc<RefCell<T>>>

You really不想尝试从Option, the Rc or the RefCell via unwrap / try_unwrap / into_inner。相反,模式匹配Option然后打电话borrow on the RefCell以获得参考T.

此外:

  1. Use if let代替match当你只关心一只手臂时的声明。
  2. 变量使用snake_case. V不是一个合适的名字。
  3. 此处无需使用结构体,也无需公开定义辅助函数。普通函数和嵌套函数更简单并且暴露的细节更少。
  4. 构造时无需提供显式类型ret.
pub fn inorder_traversal(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
    fn helper(node: &Option<Rc<RefCell<TreeNode>>>, ret: &mut Vec<i32>) {
        if let Some(v) = node {
            let v = v.borrow();

            helper(&v.left, ret);
            ret.push(v.val);
            helper(&v.right, ret);
        }
    }

    let mut ret = vec![];

    if let Some(v) = root {
        helper(&Some(v), &mut ret);
    }

    ret
}

就我个人而言,我不喜欢被迫建造Some,所以我可能会重新组织代码,这也允许我将它作为一种方法TreeNode:

impl TreeNode {
    pub fn inorder_traversal(&self) -> Vec<i32> {
        fn helper(node: &TreeNode, ret: &mut Vec<i32>) {
            if let Some(ref left) = node.left {
                helper(&left.borrow(), ret);
            }

            ret.push(node.val);

            if let Some(ref right) = node.right {
                helper(&right.borrow(), ret);
            }
        }

        let mut ret = vec![];
        helper(self, &mut ret);
        ret
    }
}

也可以看看:

  • 为什么 Arc::try_unwrap() 会导致恐慌?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 Option>> 解开并访问 T 的相关文章

随机推荐

  • 为什么不能将 RandomAccessFile 转换为 Inputstream?

    当我执行此转换时出现编译错误 RandomAccessFile raf new RandomAccessFile InputStream is InputStream raf RandomAccessFile应该是子类InputStream
  • 如何为浏览器提供“图像另存为”选项按钮

    我正在做一个画布绘图项目 我将画布转换为图像 然后将该图像另存为 png 我必须右键单击图像并选择 图像另存为 选项 但我想通过一个按钮提供该选项 当我单击按钮时 它应该被保存 任何例子或想法将不胜感激 这是一个将canvas转换为png的
  • Xamarin EditText 输入类型 密码

    我有一些EditText从 JSON 文件创建的字段 因此我无法更改 XML 文件 但我想要一些EditText输入类型为 密码 的字段 我在 Xamarin Studio 中使用 C 工作 我得到了类似的东西 但不起作用 editText
  • 如何在引导程序中将徽章放置在“媒体”的右下角?

    使用引导程序media功能 我如何放置badge在媒体块图像的右下角 所以它在图像的顶部 有了这样的标记 div class media a class pull left href img class media object src h
  • 使用 AppleScript 修改设置/系统首选项

    我正在尝试制作一个可以切换空间自动重新排列的 AppleScript 我能够让 AppleScript 打开系统首选项并进入任务控制设置 但是我不确定如何选中我想要更改的框 tell application System Preferenc
  • 根据路线动态插入 CSS 类到导航栏

    Vue 2 和 Vue Router 2 我正在尝试根据访问的路线更改应用程序导航栏的颜色 这是我所拥有的 main js import App from components App vue const app new Vue route
  • Excel VBA 打开 Word 模板,填充,然后在其他位置另存为 .docx 文件

    我创建了一个带有占位符 例如 的 Word 模板 然后我可以将其自动替换为 Excel 宏 当我再次尝试此过程时 Word 文档现在打开 显示它是只读文档 我该如何保存我的 Word 模板以便对其进行编辑 另外 当我通过excel宏打开wo
  • 尝试使用 GNU GMP 库中的类型作为 Bison 的 yylval 类型时出错

    我正在尝试使用该类型mpz t来自 GMP 库的类型yylval通过在 Bison 文件中包含以下内容 define api value type mpz t 我检查了生成的解析器 它正确生成了该行typedef mpz t YYSTYPE
  • Django 1.4 - {{ request.user.username}} 不在模板中呈现

    在我看来 我可以打印request user username 但是在模板中 request user username 不会出现 为了简单起见 我从函数中删除了逻辑 并导入 render to response 和 RequestCont
  • 错误“超出最大更新深度。当组件在 useEffect 中调用 setState 时可能会发生这种情况”

    每当调用我的购物车组件 也如下所示 时 我都会遇到此错误 重复数千次 直到页面崩溃 index js 1 Warning Maximum update depth exceeded This can happen when a compon
  • 如何根据依赖关系进行排序?

    我有一个类 其中包含指向相同基类型的其他类的 依赖项 列表 class Foo Base dependencies class Bar Base dependencies Foo class Baz Base dependencies Ba
  • PyInstaller 文件无法执行脚本 - DistributionNotFound

    我正在尝试使用 PyInstaller 将 python 文件转换为可执行文件 该程序使用谷歌云翻译 API在语言之间翻译给定文本 跑步时python quicktrans py在终端中 程序运行良好 然后我跑了pyinstaller qu
  • Xcode - 未连接配置的 iOS 设备

    今天下午我正在使用 Xcode 并在我的设备上调试应用程序 效果很好 当我从办公室回到家并插入手机继续工作时 XCode 将不再让我在设备上进行调试 我收到的错误是 Error Starting Executable No provisio
  • Pandas 最大值指数

    我有一个混合了屏幕名称 推文 收藏夹等的 Pandas DataFrame 我想找到 favcount 的最大值 我已经完成了 并返回该 推文 的屏幕名称 df pd DataFrame df timestamp timestamp df
  • SSRS如何添加新行

    我正在从这样的存储过程创建一个字符串Name1 Name2 Name 3 等等 该字符串位于一列中 我想在 SSRS 报告中的新行中显示这些名称 例如 Name1 Name2 Name3 我尝试将字符串更改为 Name1 VbCrlf Na
  • 从 http 基本身份验证中排除特定的 cakephp 控制器

    我试图排除路径 URI 被基本 http 身份验证阻止 路径是 rest http example com rest 并代表 cakephp 3 应用程序的控制器 它不是一个真实的文件 而是一个由重写条件重写并由 webroot 目录中的
  • r sf包多边形内的质心

    我需要向多边形添加标签 并且通常使用质心 但是质心不会落在多边形内 我发现这个问题计算 SpatialPolygon 内 内部的质心但我正在使用 sf 包 下面是玩具数据 rm list ls all TRUE start with emp
  • 绘制矩形和Interface Builder之间的颜色差异?

    简而言之 我在界面生成器中有 2 个视图 其中一个使用界面生成器中的 RGB 滑块设置为颜色 99 99 99 另一个视图以编程方式着色以实现某种形状 我使用以下方式填充它 Obviously this is in drawRect UIC
  • 如何修改非常大的 zip 中的单个文件而不重写整个 zip?

    我有包含巨大文件的大型 zip 文件 zip 存档中有一些需要修改的 元数据 文本文件 但是 无法提取整个 zip 并重新压缩它 我需要在 zip 中找到目标文本文件 对其进行编辑 并可能将更改附加到 zip 文件中 文本文件的文件名始终相
  • 从 Option>> 解开并访问 T

    我正在尝试用 Rust 解决一些 Leetcode 问题 然而 我在使用 LeetCode 时遇到了一些困难TreeNode执行 use std cell RefCell use std rc Rc TreeNode data struct