在Rust中将Vec <Box <Foo >>转换为&[&Foo]

时间:2019-09-07 08:16:47

标签: reference rust type-conversion slice

我正在结构上实现一种方法,该结构应通过借用&[&Foo]字段来返回Vec<Box<Foo>>。我将如何实施?

我试图通过将Vec<Box<Foo>>映射到Vec<&Foo>来进行转换,但是随后将其分配到堆栈上,这意味着无法返回其中的一部分。

以下是问题的一个示例:

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?
    }
}

1 个答案:

答案 0 :(得分:3)

您可以使用unsafe强制执行此操作:

pub fn buzz(&self) -> &[&Foo] {
    unsafe {
        std::slice::from_raw_parts(self.baz.as_ptr() as *const _, self.baz.len())
    }
}

之所以听起来如此,是因为:

  1. 如果Foo是动态大小的,则Box<Foo>是一个胖指针。但是&Foo也是如此,因此它们始终具有相同的布局。
  2. 该功能签名规定,借用的生存期不能超过&self的借用,因此,借用时不能放下盒子。

正如其他人在评论中所暗示的那样,如果您发现表面上简单的情况需要不安全的代码,而std却无法满足您的要求,那么您可能正在自己的代码库中做出错误的设计决策。尽可能避免使用unsafe,并仔细考虑应用程序的整个设计。