Reputation: 25
I am implementing a method on a struct which should return a &[&Foo]
by borrowing a Vec<Box<Foo>>
field. How would I implement this?
I have tried to do the conversion by mapping the Vec<Box<Foo>>
into a Vec<&Foo>
, however this is then allocated on the stack meaning a slice of it cannot be returned.
Here is an example of the problem:
struct Bar {
baz: Vec<Box<Foo>>,
}
impl Bar {
pub fn buzz(&self) -> &[&Foo] {
// How do I implement this to return
// the data that is in self.baz?
}
}
Upvotes: 1
Views: 188
Reputation: 58735
You can do it with an unsafe
coercion:
pub fn buzz(&self) -> &[&Foo] {
unsafe {
std::slice::from_raw_parts(self.baz.as_ptr() as *const _, self.baz.len())
}
}
This is sound because:
Foo
is dynamically sized, then Box<Foo>
is a fat pointer. But then so is &Foo
, so they always have the same layout.&self
, so it is not possible for the boxes to be dropped while borrowed.As others have hinted in comments, if you find yourself needing unsafe code for ostensibly simple cases, not catered for by std
, then you may be working around a bad design decision in your own codebase. Avoid unsafe
wherever possible and look critically at the entire design of your application before considering using it.
Upvotes: 3