Как не заимствовать опцион при сопоставлении?

У меня есть следующий код:

fn remove_descendent(&mut self, key: &K) -> Option<V> {
    if self.left.is_some() && self.left.as_ref().unwrap().key == *key {
        return self.remove_left();
    }

    // more of the function
}

Это грубо для меня. Вместо проверки is_some а затем развернуть. Я подумал, что мне действительно следует использовать выражение соответствия, чтобы деконструировать Option представлен left переменная вот так:

fn remove_descendent(&mut self, key: &K) -> Option<V> {
    match self.left {
        Some(ref left) if left.key == *key => self.remove_left(),
        _ => None
    }

Однако, когда я делаю это, я получаю следующую ошибку:

error[E0502]: cannot borrow `*self` as mutable because `self.left.0` is also borrowed as immutable
  --> src/lib.rs:29:51
   |
29 |             Some(ref left) if left.key == *key => self.remove_left(),
   |                  --------                         ^^^^ mutable borrow occurs here
   |                  |
   |                  immutable borrow occurs here
30 |             _ => None
31 |         }
   |         - immutable borrow ends here

Я полагаю, я понимаю, что я не могу безошибочно одолжить член структуры, а затем непостоянно заимствовать структуру. Но если это так, то как правильно сопоставить шаблон с моим Option? Есть один?

1 ответ

Компилятор жалуется, потому что в руке матча self все еще заимствован. Вы можете обойти это с клонированием key заранее:

fn remove_descendent(&mut self, key: &K) -> Option<V> {
    match self.left.clone() {
        Some(ref left) if left.key == *key => self.remove_left(),
        _ => None,
    }
}

Вы можете увидеть это в действии на игровой площадке.

С включенным Non Lexical Lifetimes ваш код компилируется просто отлично: Playground.

Другие вопросы по тегам