How to convert Vector of Box to Vector of reference?
Asked Answered
C

1

5

I'm looking for a way to conver Vec<Box<u32>> to Vec<&u32>. Here is what I tried:

fn conver_to_ref(){
    let test: Vec<Box<u32>> = vec![Box::new(1), Box::new(2)];
    let _test2: Vec<&u32> = test.into_iter().map(|elem| &*elem).collect();
}

Unfortunately it does not compile: demo. The error message:

error[E0515]: cannot return reference to local data `*elem`
 --> src/lib.rs:3:57
  |
3 |     let _test2: Vec<&u32> = test.into_iter().map(|elem| &*elem).collect();
  |                                                         ^^^^^^ returns a reference to data owned by the current function

How to do such conversion?

Cacka answered 21/8, 2020 at 14:44 Comment(0)
C
7

into_iter() consumes the original vector and its items. If the code compiled as written, all the references in _test2 would be dangling because the boxes would be destroyed along with test.

You can build a vector of references, but you will need to not consume the original test vector, so that the boxes retain an owner. You can simply use iter() instead of into_iter():

fn convert_to_ref() {
    let test: Vec<Box<u32>> = vec![Box::new(1), Box::new(2)];
    let _test2: Vec<&u32> = test.iter().map(Box::as_ref).collect();
}

Note that test.iter() yields references to test elements, i.e. to the boxes themselves (&Box<u32>), and not to the boxed items (&u32) which we're interested in. This is why we must apply as_ref to get the latter.

Chatham answered 21/8, 2020 at 14:56 Comment(3)
Also elem.to_ref() which is nicer than &**.Principle
@Principle It's as_ref(), but yes, much nicer. Amended the answer.Chatham
@SomeName The error message is one of those that is clear once you know what's going on. into_iter() destroys the vector and transfer ownership of its items into the iterator, which in turn transfers them to its users, including adapters like map(). So when the compiler complains that elem is "owned by the current function", the function refers to the closure. Returning a reference to a locally owned value, even though it's boxed, would immediately create a dangling reference, as the box would be destroyed on return from the closure.Chatham

© 2022 - 2024 — McMap. All rights reserved.