Is there a way to avoid always allocating rd
in line A?
pub fn main(
render_data_opt: Option<&mut Vec<usize>>,
) {
let mut rd = Vec::new(); // (A)
let render_data = render_data_opt.unwrap_or_else(|| &mut rd);
// (Use render_data)
}
Whether there are other ways to do this that don’t involve a Vec::new()
call might depend on how render_data
is actually used. Maybe the type that’s needed for the usage isn’t actually &mut Vec<usizize>
because perhaps mutating – or at least growing – the Vec
doesn’t even happen.
Regarding allocations, note that Vec::new()
itself does not yet actually allocate anything. Only of the usage of render_data
were to fill the Vec
with data, e.g. with .push(…)
, would allocation happen, but if that is the case, I’d need to question what the imagined solution without any allocations is supposed to look like in the first place.
1 Like
If you're literally using Vec::new
, like @steffahn said, don't worry about it -- it's cheap and doesn't allocate.
If the initialization is actually costly, you can do something like this.
pub fn weird_main(render_data_opt: Option<&mut Vec<usize>>) {
let mut rd = Vec::new();
let render_data = render_data_opt.unwrap_or_else(|| {
rd.reserve(1_000_000);
&mut rd
});
}
2 Likes
Like this (if that didn’t cause lifetime issues):
pub fn main(
render_data_opt: Option<&mut Vec<usize>>,
) {
let render_data = render_data_opt.unwrap_or_else(|| &mut Vec::new());
// (Use render_data)
}
In my code, render_data_opt
is not based on Vec
and an optional input&output parameter.
I may have to restructure my code so that it is moved in and returned (in addition to the actual result of the function, e.g. via a tuple).
I don't think you can initialize in a closure, but you can do this.
pub fn weird_main(render_data_opt: Option<&mut Vec<usize>>) {
let mut rd;
let render_data = match render_data_opt {
Some(thing) => thing,
None => {
rd = Vec::with_capacity(1_000_000);
&mut rd
}
};
}
4 Likes
Well, here's a closure-friendly way.
pub fn weird_main(render_data_opt: Option<&mut Vec<usize>>) {
let mut rd = None;
let render_data = render_data_opt.unwrap_or_else(|| {
rd.insert(Vec::new())
});
}
2 Likes
Both of these are great, thanks!