使用 Rc 实现二叉树时,不能将不可变的借用内容借用为可变的 [英] Cannot borrow immutable borrowed content as mutable when implementing a binary tree with Rc

查看:80
本文介绍了使用 Rc 实现二叉树时,不能将不可变的借用内容借用为可变的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现一个二叉树.我的主要语言是 C++,所以代码可能不是惯用的 Rust,而是编译以下代码:

I want to implement a binary tree. My main language is C++ so the code is probably not idiomatic Rust, but compiling the following code:

use std::rc::Rc;

struct Node {
    left: Option<Rc<Node>>,
    right: Option<Rc<Node>>,
    data: String,
}


impl Node {
    fn new(_data: String) -> Node {
        Node {
            data : _data.clone(),
            left : None,
            right : None,
        }
    }

    fn insert_left(&mut self, mut node: &Rc<Node>) {
        self.left = Some(node.clone());
    }

    fn insert_right(&mut self, mut node: &Rc<Node>) {
        self.left = Some(node.clone());
    }
}

fn main() {
    let mut root = Rc::new(Node::new(String::from("root")));
    let mut left = Rc::new(Node::new(String::from("left")));
    root.insert_left(&left);
}

我有编译错误:

error: cannot borrow immutable borrowed content as mutable
  --> so.rs:31:9
   |
31 |         root.insert_left(&left);
   |         ^^^^

error: aborting due to previous error

我不明白这里有什么问题.经过一些尝试错误的迭代后,我发现问题出在 insert_left() 函数中:如果 self 是一个不可变的引用,那么它会使用注释掉的内容进行编译,但是不可变的引用不允许我实现我的目标.

I can't understand what is wrong here. After some try-mistake iterations I found out that problem lies in the insert_left() function: if self is an immutable reference, then it compiles with commented out content, but an immutable reference does not allow my to accomplish my goal.

推荐答案

这是您的问题的 MCVE:

use std::rc::Rc;

struct Node;

impl Node {
    fn insert_left(&mut self) {}
}

fn main() {
    let root = Rc::new(Node);
    root.insert_left();
}

您可以通过删除尽可能多的代码来获得这样的示例,同时仍然出现相同的错误.这个过程非常有助于加深对问题的理解.

You can arrive at an example like this by removing as much code as possible while still getting the same error. This process helps tremendously to build understanding of the problem.

问题在于 Rc 不允许任何类型的突变.正如文档中所述:

The problem is that Rc disallows mutation of any kind. As stated in the documentation:

Rust 中的共享指针默认不允许突变,Rc 也不例外.如果您需要通过 Rc 进行变异,请使用 CellRefCell.

Shared pointers in Rust disallow mutation by default, and Rc is no exception. If you need to mutate through an Rc, use Cell or RefCell.

因此,没有办法从 Rc&mut Foo,这将需要调用 insert_left方法.

Therefore, there's no way to go from a Rc<Foo> to a &mut Foo, which would be needed to call the insert_left method.

如文档所述,您可以使用允许内部可变性的类型之一,例如 CellRefCell.这些功能有点像互斥锁,但对多线程场景无效.它们确保一次只有一个值的可变引用可用,这是 Rust 安全的关键组成部分.

As documented, you can use one of the types that allows interior mutability, such as a Cell or RefCell. These function a bit like a mutex, but are not valid for multithreaded scenarios. They ensure that only one mutable reference to a value is available at a time, a key component of Rust's safety.

如果您不需要 Rc 的共享功能,您也可以使用 Option<Box<Node>>.

If you don't need the functionality of Rc's sharing, you can just move to having an Option<Box<Node>> as well.

这篇关于使用 Rc 实现二叉树时,不能将不可变的借用内容借用为可变的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆