使用 Rc 实现二叉树时,不能将不可变的借用内容借用为可变的 [英] Cannot borrow immutable borrowed content as mutable when implementing a binary tree with 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
进行变异,请使用 Cell
或 RefCell
.
Shared pointers in Rust disallow mutation by default, and
Rc
is no exception. If you need to mutate through anRc
, useCell
orRefCell
.
因此,没有办法从 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.
如文档所述,您可以使用允许内部可变性的类型之一,例如 Cell
或 RefCell
.这些功能有点像互斥锁,但对多线程场景无效.它们确保一次只有一个值的可变引用可用,这是 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屋!