Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How can I add an item to a struct member that is an `Option<Vec<…>>`?

How can I add an item to a struct member that is an Option<Vec<...>>?

In other words, what do I need to to to make add_foo below work?

struct Foo {
    value: u32,
}

struct Bar {
    foos: Option<Vec<Foo>>, 
}

impl Bar {
    fn add_foo(&mut self, foo: Foo) {
        if self.foos.is_none() {
            self.foos = Some(vec![]);
        }
        self.foos.unwrap().push(foo);
//      ^^^^^^^^^ move occurs because `self.foos` has type `Option<Vec<Foo>>`, which does not implement the `Copy` trait        
    }
}

fn main() {
    let mut bar = Bar{foos: None};
    bar.add_foo(Foo{value:42});
}

The error message suggests adding as_ref() but that doesn’t help:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

        self.foos.as_ref().unwrap().push(foo);
//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable

I though there might be something as as_mutref() but there is no such thing. Since I already hold a mutable reference to the Bar struct, I would expect to be able to change the foos field in the Bar struct.

Apologies if my terminology is off; still getting used to the whole Rust ownership concept.

>Solution :

Something like the following might be what you’re looking for:

fn add_foo(&mut self, foo: Foo) {
  if let Some(foos) = self.foos.as_mut() {
    // foos has type: &mut Vec<Foo>
    foos.push(foo);
  } else {
    self.foos = Some(vec![foo]);
  }
}

In general, using an if let or match or some other destructuring syntax is considered more idiomatic than using a is_some() check followed by an unwrap(). At the very least it saves on a comparison, but more importantly is harder to make accidentally panic.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading