简体   繁体   中英

How do I not borrow an Option when matching?

I have the following code:

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
}

This feels gross to me. Instead of checking is_some and then unwrapping. I figured what I really should be doing is using a match statement to deconstruct the Option represented by the left variable like so:

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

However, when I do this I get the following error:

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

I guess I get that I can't immutably borrow a structs member and then mutably borrow the struct. But if that's the case, what's the proper way to pattern match my Option ? Is there one?

The compiler complains because in the match arm self is still borrowed. You can get around this with cloning the key beforehand:

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

You can see this in action on the Playground .

With Non Lexical Lifetimes enabled, your code compiles just fine: Playground .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM