1

I'd like to edit the content inside an Option<T> without consuming it. The code below seems one way, but I think the use of get_or_insert() is somewhat unnecessary and redundant.

#[derive(Debug)]
struct S {
    state: String,
}

fn main() {
    let mut x = Some(S {
        state: String::from("Some is definitely set"),
    });
    let y: &mut S = x.get_or_insert(S {
        state: String::from("Just hack. This is definitely not going to be inserted"),
    });
    y.state = String::from("Check out x");
    println!("{:#?}", x);
}

Is there an alternative to get_or_insert() to pull out reference of Option<T> without consuming it?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Jeon
  • 4,000
  • 4
  • 28
  • 73
  • 1
    I don't follow your logic. You have an `Option`, which means you don't know if the data is present or not. There's no way to get a reference to the data to mutate it if the `Option` is `None`. How would you want it to be more efficient? What should happen when it's `None`? – Shepmaster Jun 03 '20 at 15:26
  • I guess `x.get_or_insert_with(|| None)` might be a little nicer (since it ensures that if the option is `None`, it stays `None`) but still -- it's an awkward construct. – Frerich Raabe Jun 03 '20 at 15:28
  • @Shepmaster Well, to simplify, what I want is another version of `unwrap()` which panics or returns a reference. – Jeon Jun 03 '20 at 15:28
  • It looks like your question might be answered by the answers of [Cannot cannot move out of value which is behind a shared reference when unwrapping](https://stackoverflow.com/a/32338976/155423). If not, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Jun 03 '20 at 15:29
  • 1
    [The duplicate applied to your case](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=2e11caad317657ab8b02cac8468b8c10) – Shepmaster Jun 03 '20 at 15:30

1 Answers1

0

After reading your comment, I guess you're after x.as_mut().unwrap():

#[derive(Debug)]
struct S {
    state: String,
}

fn main() {
    let mut x = Some(S {
        state: String::from("Some is definitely set"),
    });
    x.as_mut().unwrap().state = String::from("Check out x");
    println!("{:#?}", x);
}
phimuemue
  • 34,669
  • 9
  • 84
  • 115