[使用方法调用的结果时多次可变借用

问题描述 投票:0回答:1

在此简化的代码中,我有两个重要的结构:Owner获取对象的所有权,将其添加到Vec,并返回对该对象的引用; RefKeeper仅保留对Vec中对象的引用。 Owner也有一个RefKeeper

struct Foo(i32);

struct Owner<'o> {
    list: Vec<Foo>,
    refkeeper: RefKeeper<'o>,
}

impl<'o> Owner<'o> {
    pub fn new() -> Self {
        Self {
            list: Vec::new(),
            refkeeper: RefKeeper::new(),
        }
    }

    pub fn add(&mut self, me: Foo) -> &Foo {
        self.list.push(me);
        return self.list.last().unwrap();
    }

    pub fn add_ref(&mut self, me: &'o Foo) {
        self.refkeeper.add(me);
    }
}

struct RefKeeper<'ro> {
    list: Vec<&'ro Foo>,
}

impl<'ro> RefKeeper<'ro> {
    pub fn new() -> Self {
        Self { list: Vec::new() }
    }

    pub fn add(&mut self, me: &'ro Foo) {
        self.list.push(me);
    }
}

fn main() {
    let mut owner = Owner::new();
    let a1 = Foo(1);
    let a1_ref = owner.add(a1);

    // this variant doesn't work
    owner.add_ref(a1_ref);

    // let mut refkeeper = RefKeeper::new();
    // refkeeper.add(a1_ref);

    // let a2 = Foo(2);
    // owner.add_ref(&a2);
}

有两种变体:如果我在外部制作RefKeeper,则可以存储Owner::add返回的引用;另一方面,如果我创建一个新对象(a2),则可以毫无问题地将&a2存储在owner.refkeeper中。为什么其他变体会给我这个错误?

error[E0499]: cannot borrow `owner` as mutable more than once at a time
  --> src/main.rs:46:5
   |
43 |     let a1_ref = owner.add(a1);
   |                  ----- first mutable borrow occurs here
...
46 |     owner.add_ref(a1_ref);
   |     ^^^^^         ------ first borrow later used here
   |     |
   |     second mutable borrow occurs here

这种模式是否存在根本性的错误?我觉得生命周期应该没有问题,因为所有借用都在同一个对象中使用。

rust borrow-checker borrowing
1个回答
0
投票

这是因为Owner::add返回绑定到&mut self生存期的引用。因此,只要返回值存在(a1_ref),那么&mut self引用也是如此。因此,调用add_ref失败,因为它需要该实例的另一个mut self引用。

您可以具有一个可变引用,也可以具有多个不可变引用。

之所以先调用refkeeper.add,然后再调用owner.add_ref并没有给您同样的问题,是因为添加到refkeeper不需要再次引用owner

您可能想看看std::rc::Rc

© www.soinside.com 2019 - 2024. All rights reserved.