rust - 使用 Rc 实现二叉树时,不能将不可变借用内容借用为可变内容

标签 rust

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

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 是一个不可变引用,那么它会使用注释掉的内容进行编译,但是不可变引用不允许我实现我的目标。

最佳答案

这是一个 MCVE你的问题:

use std::rc::Rc;

struct Node;

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

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

您可以通过删除尽可能多的代码而仍然得到相同的错误来得出这样的示例。此过程极大地有助于建立对问题的理解。

问题是 Rc不允许任何类型的突变。作为stated in the documentation :

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<Foo> 开始到 &mut Foo ,这将需要调用 insert_left方法。

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

如果您不需要 Rc 的功能的分享,你可以转移到拥有Option<Box<Node>>

关于rust - 使用 Rc 实现二叉树时,不能将不可变借用内容借用为可变内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41045011/

相关文章:

reference - 为什么 Option::map 不在 Iterator::next 的链表实现中取得所有权?

string - 切片字符串会复制底层数据吗?

rust - 如何使从 HashMap::get 返回的 Some 的值可变?

javascript - WebAssembly InstantiateStreaming 错误的 MIME 类型

rust - 如何使用泛型数组?

rust - cargo 建立时“A fatal alert message was received from our peer” SSL错误

rust - 为什么不能在结构定义中省略生命周期?

rust - 防 rust 反序列化: converting vector of bytes to hashset of uuid

rust - 不能在不可变切片可以使用的地方使用可变切片

arguments - 是否可以根据参数计算 Rust 函数或特征方法的返回类型?