无法从对 Option 的可变引用后面移出

Cannot move out from behind mutable reference to Option

我有一个结构:

struct Foo<'a> {
    parent: Option<&'a mut Foo<'a>>,
    value: i32,
}

impl<'a> Foo<'a> {
    fn bar(&mut self) {
        if let Some(&mut parent) = self.parent {
            parent.bar();
        } else {
            self.value = 1;
        }
    }
}

但是我得到错误:

error[E0507]: cannot move out of `*self.parent.0` which is behind a mutable reference
 --> src/lib.rs:8:36
  |
8 |         if let Some(&mut parent) = self.parent {
  |                          ------    ^^^^^^^^^^^ help: consider borrowing here: `&self.parent`
  |                          |
  |                          data moved here
  |                          move occurs because `parent` has type `Foo<'_>`, which does not implement the `Copy` trait

error[E0596]: cannot borrow `parent` as mutable, as it is not declared as mutable
 --> src/lib.rs:9:13
  |
8 |         if let Some(&mut parent) = self.parent {
  |                          ------ help: consider changing this to be mutable: `mut parent`
9 |             parent.bar();
  |             ^^^^^^ cannot borrow as mutable

我已经尝试了该行的许多变体,但无法正常工作。我该怎么做?

在您的 if let 语句中,您试图解构 self.parent 以获得 parent,甚至获得后面的 Foo (本身,作为一个值)存储的引用。

您必须添加一个额外的间接级别来引用可能存在或可能不存在的 &mut Foo,如果它存在,则不将其从 Option 中删除。

if let Some(ref mut parent) = self.parent {

if let Some(parent) = self.parent.as_mut() {

您在这两种情况下获得的 parent 绑定都具有类型 &mut &'a mut Foo<'a>,因此 automatic-dereference 将在调用 parent.bar().

时出现

nb:我使用提醒 « = 的 left-hand-side 上的 ref 类似于 [=44= 上的 & ]»,但是这里我们要在里面加上&Option,所以使用.as_ref()或者.as_mut() 取决于预期的可变性。