借用亲子关系检查器

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)

She*_*ter 2

并且错误中的可变/不可变单词不相关

我不知道你为什么这么想。可变性在 Rust 中非常重要!例如,虽然允许您同时对不可变数据进行多个引用,但一次只允许对可变数据进行单个引用。

首先,您需要修复 的可变性parent

let mut parent = // ...
Run Code Online (Sandbox Code Playgroud)

然后,您将从该行收到错误:

parent.child.use_parent(&mut parent);
Run Code Online (Sandbox Code Playgroud)

当您运行此行时,您隐式可变地借用了parentchild。这样做是为了您可以调用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 的模块文档,其中有一个正是这种父子关系的示例。