问题描述
我有下面的代码产生在其注释中标记的错误消息.我想我理解这个信息:我想借用 parent 两次:一次是为了找到它的孩子,一次是作为孩子的参数(错误中的可变/不可变词不相关).我必须证明 Child
在修改 Parent
时不会消失.但我不知道如何做到这一点.我可以Rc<Child>
除了接缝浪费之外的所有内容,所以我希望添加一些生命周期可以解决问题.
I have the code below producing the error message marked in its comments. I think I understand the message: I want to borrow parent two times: once for finding its child, and once as an argument to the child (and the mutable/immutable words in the error are not relevant). I have to prove that Child
doesn't disappear when it modifies Parent
. But I don't know how to do this. I could Rc<Child>
everything but that seams wasteful, so I hope adding some lifetimes would do the trick.
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);
}
推荐答案
我不知道你为什么这么认为.可变性在 Rust 中非常很重要!例如,虽然您可以同时引用多个不可变数据,但一次只能引用一个可变数据.
I'm not sure why you think this. Mutability is very important in Rust! For example, while you are allowed multiple references to immutable data at the same time, you are only allowed to have a single reference to mutable data at a time.
首先需要修复parent
的可变性:
First, you need to fix the mutability of parent
:
let mut parent = // ...
然后,你会得到一行错误:
Then, you will get an error from the line:
parent.child.use_parent(&mut parent);
当您运行此行时,您隐式地可变地借用了 parent
和 child
.这样做是为了您可以调用 use_parent
,这需要 &mut self
.
When you run this line, you are implicitly mutably borrowing parent
and child
. This is done so that you can call use_parent
, which requires a &mut self
.
然而,您也试图获得第二个可变引用作为参数!这是一个禁忌,因为如果允许您有多个 别名 可变引用,编译器将无法跟踪它并确保您不会破坏内存安全保证.
However, you are also trying to get a second mutable reference as the argument! This is a no-no, because if you were allowed to have multiple aliasing mutable references, the compiler wouldn't be able to track it and make sure that you don't break the memory-safety guarantees.
假设我删除了 self.dummy+=1;
行,所以只有 1 个可变别名 - 我可以让它工作吗?
让我们看看函数签名的一些变体
Let's look at some variations of the function signature
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
正如我之前提到的,如果你有一个对某事物的可变引用,你就不能有对同一事物的任何其他引用(无论是否可变).
As I mentioned earlier, if you have a mutable reference to something, you aren't allowed to have any other references to that same thing (mutable or not).
另外,请注意方法的主体是什么并不重要!Rust 只检查被调用函数的签名以验证借用某些东西是否安全.
Also, note that it doesn't matter what the body of the method is! Rust only checks the signature of a called function to verify if it's safe to borrow something.
那么您如何尝试解决您的问题?最终,您正在尝试做一些编译器很难证明安全的事情.你想要一个可变链接的图.我强烈建议阅读 Rc 的模块文档,其中有一个示例正是这种亲子关系.
So how do you try to solve your problem? Ultimately, you are trying to do something that is very difficult for the compiler to prove safe. You want a graph of mutable links. I'd highly suggest reading the module documentation for Rc which has an example of exactly this parent-child relationship.
这篇关于亲子关系借用检查器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!