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:
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With