I'd like to move some Boxed values from one Vec to another, but I can't figure out if this is possible or whether I'm thinking about it wrong.
So far, my smallest example of the problem is:
#[derive(Debug)]
pub struct B {
value: usize
}
fn main() {
let v1: Vec<_> = (1..3).map(|i| Box::new(B{ value: i})).collect();
let v2: Vec<Box<B>> = v1.iter().map(|b| *b).collect();
println!("{v2:?}");
}
Which gives the error:
error[E0507]: cannot move out of `*b` which is behind a shared reference
--> src/main.rs:8:45
|
8 | let v2: Vec<Box<B>> = v1.iter().map(|b| *b).collect();
| ^^ move occurs because `*b` has type `Box<B>`, which does not implement the `Copy` trait
I've tried various (but possibly incorrect) methods of trying to move the contents of the Box with std::mem::swap and friends, but haven't managed to get that right.
For clarity, I want to avoid copying the B's - in reality they are large. I haven't experimented with an Rc, and ideally I'd avoid that. v1 is effectively consumed when it is mapped into v2.
As shown above, the example is pretty uninteresting, in the "real" case, v1 is a Vec of 2-tuples, and I'd like to map it to a Vec of 3-tuples with an extra element derived from the first two.
I'm aware I don't need all the type annotation, but that helps check I'm getting what I want. For a while I thought I had succeeded, but was actually getting a Vec<&Box<B>> (or similar, don't take my exact word for it).
Does anyone have any insight as to how to do this, or how I can approach the problem differently? Thanks!