何时使用Box<Vec<..>>或Vec<Box<..>>?

11

什么情况下设计一个嵌套了 BoxVec(或反之亦然)的数据结构是有意义的呢?

看起来,在大多数需要在堆上存储多个固定大小的值的情况下,Box 是多余的,因为它唯一的 (?) 作用是在堆上分配单个值,而普通的 Vec 已经在堆上分配了它的存储空间。

上下文: 我仍在琢磨用于构建数据结构的各种 Rust 类型的作用。


1
我能想到的唯一用例涉及不安全的行为,比如希望堆中的对象具有固定的指针位置,即使 Vec 重新分配内存。 - Levans
2个回答

16

只有在以下几种情况下才需要使用Box

  • 递归数据结构:对于最外层元素没有影响,因此不需要Vec<Box<T>>

  • 拥有trait对象,该对象必须是Box<Trait>,因为对象的大小是动态的;

  • 某些内容对特定内存地址敏感,以便所包含的对象将保持相同的内存位置(实际上几乎从未发生,绝对不会在任何稳定的公共API中发生;与std::sync::mpsc::Select相关的一些处理是我所知道的唯一情况;这种不安全和注意事项是select!存在的原因之一。这种情况(Handle.add)是不安全的。

如果没有这些情况适用,你不应该使用Box。而Box<Vec<T>>就是这样一种情况;盒装是完全多余的,增加了额外的间接层,没有任何好处。
所以简单版本是:
  • Box<Vec<T>>: 永远不要使用。
  • Vec<Box<T>>: 只有在T是一个trait时,也就是你正在使用trait对象时才使用。

0

Box<Vec<T>> 在某些罕见的情况下可以与 Option<Box<Vec<T>>> 一起使用,如果你想要缩小结构体的大小 (从三个字变成一个字) 并且该向量通常是空的。例如在 rustc 中就被用于此目的。然而,最近已经被 thin-vec 库替换了, 它做得更好(通过将长度和容量内联存储,仍然只需要一个字,因此不需要太多分配内存)。如果您不想引入依赖项,这仍然可能很有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接