我想实现一个二叉树。我的主要语言是 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 anRc
, useCell
orRefCell
.
因此,没有办法从 Rc<Foo>
开始到 &mut Foo
,这将需要调用 insert_left
方法。
如文档所述,您可以使用允许内部可变性 的类型之一,例如 Cell
或 RefCell
.这些功能有点像互斥锁,但对多线程场景无效。它们确保一次只有一个值的可变引用可用,这是 Rust 安全性的关键组成部分。
如果您不需要 Rc
的功能的分享,你可以转移到拥有Option<Box<Node>>
关于rust - 使用 Rc 实现二叉树时,不能将不可变借用内容借用为可变内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41045011/