How can one "Set if unset"


#1

One more awkward beginner-question please!

struct MyStruct {
  s: Option<String>
}

impl MyStruct {
  fn setIfUnset(&mut self) {
    match &mut self.s {
      & mut Some(ref s) => { /* omitted here */}
      & mut None => {
         self.s = Some(String::from(" I Wandered Lonely as a Cloud "))
      }
    }
  }
}

Compiler claims an error:
& mut None => self.s = Some(String::from(" I Wandered Lonely as a Cloud "))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed self.s occurs here

But how am I supposed to set “self.s” in the case, it is none?
“self.s is borrowed” - OK. But how can I access this borrow?

Benedikt


#2

You can bind to the matched pattern like so:

    match &mut self.s {
      & mut Some(ref s) => { /* omitted here */}
      s @ & mut None => {
         *s = Some(String::from(" I Wandered Lonely as a Cloud "))
      }
    }

#3

Also consider using Option::get_or_insert_with:

fn setIfUnset(&mut self) {
        self.s
            .get_or_insert_with(|| String::from(" I Wandered Lonely as a Cloud "));
}

#4

I love you guys! :slight_smile:

Documented in https://doc.rust-lang.org/reference/expressions/match-expr.html

Thanks!
Benedikt