I need to initiate an &mut T where Option<&mut T> returns None. I'm quite a fan of single lines like unwrap_or_else and such methods, and wish to do something like the following:
However it doesn't work of course, because the closure creates then drops the Vec. So I need to do something like the following:
fn maybe_takes_mutable_reference_two(optional_value: Option<&mut Vec<usize>>) {
if let Some(passed_vec) = optional_value {
takes_vec(passed_vec)
} else {
let mut new_vec = recreate_expensive_vec();
takes_vec(&mut new_vec);
}
}
Unfortuantly things get a little more complicated when I have a few more optional mutable references coming in, and have to match on all of them and do new allocations only when necessary. Is there a more ergonomic way to create an &mut T in less lines (without macros)?
Your second example can be simplified to this (same idea, i.e. have a vector in the scope of maybe_takes_mutable_reference_two, rather than creating it inside the closure of unwrap_or_else):
Thanks for the responses. Just to clarify, The Vec was an example. In reality the &mut T is quite a larged collection with the proper capacity and values that need to be recreated if it isn't passed in. So for the example given, we can assume that avoiding recreating the Vec is expensive. I've updated the example to reflect this.
If you have a T that does need significant work to initialize and you find yourself needing this pattern a lot, you can define a helper type to defer the initialization: