您收到错误消息的原因不同。您有一个非可变变量 parent 并试图为其创建一个 &mut。修复你得到的
let mut parent = Parent {
used: 0,
child: Child {
dummy: 1
}
};
parent.child.use_parent(&mut parent);
以及相应的错误
<anon>:31:34: 31:40 error: cannot borrow `parent` as mutable more than once at a time
<anon>:31 parent.child.use_parent(&mut parent);
^~~~~~
<anon>:31:5: 31:17 note: previous borrow of `parent.child` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `parent.child` until the borrow ends
<anon>:31 parent.child.use_parent(&mut parent);
^~~~~~~~~~~~
<anon>:31:41: 31:41 note: previous borrow ends here
<anon>:31 parent.child.use_parent(&mut parent);
^
你几乎得出了正确的结论。
我要证明 Child 在修改 Parent 时不会消失
不完全是。您必须证明您永远不会有两个&mut 或一个&mut 和一个& 给孩子。如果你有一个&mut 给父母,你可以用它来给孩子一个&mut。因此,如果你有一个&mut 给父母,一个&mut 给孩子,你可以得到两个&mut 给孩子。
我看到的唯一解决方案是将use 函数移动到Parent 类型并通过self 访问child。
impl Parent {
fn use_parent(&mut self) {
// use both child and parent
self.used += self.child.dummy;
self.child.dummy += 1;
}
}
解决您的评论:
不幸的是,该解决方案适用于这个简化的问题,但不适用于我的实际问题。父母有一个孩子的向量,它可能有深层嵌套的孙子。我不能只说self.child
由于你不应该修改你的向量(而且不能,Rust 保护你),因为这会使对子节点的引用无效,你可以将这些部分传递给你需要的函数,但没有一个部分可以是孩子的直接父母。
impl Child {
fn use_parent(&mut self, used: &mut i32) {
// use both child and parent
*used += self.dummy;
self.dummy += 1;
}
}
fn main() {
let mut parent = Parent {
used: 0,
child: Child {
dummy: 1
}
};
// although both point to elements of the same structure
// it is guaranteed at compile-time that they point to
// non-overlapping parts
let child = &mut parent.child;
let used = &mut parent.used;
child.use_parent(used);
}
不幸的是,我没有办法证明use_parent 的参数指向同一个Parent 对象的一部分。也许这可以用一生来完成,我不确定,但我会对此非常感兴趣。注意:Rc 也有同样的问题。