hyp*_*man 5 rust borrow-checker
我有下面的代码生成在其注释中标记的错误消息。我想我理解这个消息:我想借用父级两次:一次用于查找其子级,一次作为子级的参数(并且错误中的可变/不可变单词不相关)。我必须证明当Child它修改时它不会消失Parent。但我不知道该怎么做。我可以做Rc<Child>任何事,但那似乎很浪费,所以我希望增加一些生命周期就能达到目的。
struct Parent {
used: i32,
child: Child,
}
struct Child {
dummy: i32,
}
impl Child {
fn use_parent(&mut self, parent: &mut Parent) {
// use both child and parent
parent.used += self.dummy;
self.dummy += 1;
}
}
fn main() {
let parent = Parent {
used: 0,
child: Child {
dummy: 1
}
};
//Error: cannot borrow immutable local variable `parent` as mutable
parent.child.use_parent(&mut parent);
}
Run Code Online (Sandbox Code Playgroud)
并且错误中的可变/不可变单词不相关
我不知道你为什么这么想。可变性在 Rust 中非常重要!例如,虽然允许您同时对不可变数据进行多个引用,但一次只允许对可变数据进行单个引用。
首先,您需要修复 的可变性parent:
let mut parent = // ...
Run Code Online (Sandbox Code Playgroud)
然后,您将从该行收到错误:
parent.child.use_parent(&mut parent);
Run Code Online (Sandbox Code Playgroud)
当您运行此行时,您隐式可变地借用了parent和child。这样做是为了您可以调用use_parent,这需要&mut self.
但是,您还试图获取第二个可变引用作为参数!这是一个禁忌,因为如果允许您有多个别名可变引用,编译器将无法跟踪它并确保您不会破坏内存安全保证。
假设我删除了该行
self.dummy+=1;,因此只有 1 个可变别名 - 我可以让它工作吗?
让我们看看函数签名的一些变体
fn use_parent(&self, parent: &mut Parent)
// cannot borrow `parent` as mutable because `parent.child` is also borrowed as immutable
fn use_parent(&mut self, parent: &Parent)
// cannot borrow `parent` as immutable because `parent.child` is also borrowed as mutable
fn use_parent(&self, parent: &Parent)
// OK
Run Code Online (Sandbox Code Playgroud)
正如我之前提到的,如果您对某事物有可变引用,则不允许您对同一事物有任何其他引用(可变或不可变)。
另外,请注意,方法的主体是什么并不重要!Rust 只检查被调用函数的签名来验证借用某些东西是否安全。
那么你如何尝试解决你的问题呢?最终,您正在尝试做一些编译器很难证明安全的事情。您想要一个可变链接图。我强烈建议阅读Rc 的模块文档,其中有一个正是这种父子关系的示例。