如何在不单独分配堆上的每个项目的情况下创建拥有的特征对象列表?

How can I create a list of owned trait objects without allocating each item on the heap separately?

我想要一个拥有的 Rust 特征对象列表。我可以将它实现为 Vec<Box<dyn Trait>> 但它会在堆上为每个特征对象分配 space 。我更喜欢 CompactList<dyn Trait> 类型,其内存表示形式如下所示:

[vtable1, size1, data1, vtable2, size2, data2, vtable3, size3, data3]

size*是相应data*的字节大小。

有了这个,我可以创建一个 Iterator<Item = &dyn Trait>。我需要对 CompactList<T> 进行的唯一操作是 push()iter().

dynstack 板条箱可以满足您的需求。它依赖于胖指针的表示,这就是特征对象,并且这种表示在理论上可能有一天会改变。

虽然它解决了避免为每个对象分配堆的问题,但它在内存中的表示是不同的:基本上有两个列表,而不是平面列表:

  • [data1, data2, ...]
  • [(vtable1, size1), (vtable2, size2), ...]

由于 data 结构可以有不同的大小,您的表示不支持 O(1) 随机访问,而这个表示支持。 See this blog post for details.

示例,改编自文档:

use dynstack::{dyn_push, DynStack};
use std::fmt::Debug;

let mut stack = DynStack::<dyn Debug>::new();
dyn_push!(stack, "hello, world!");
dyn_push!(stack, 0usize);
dyn_push!(stack, [1, 2, 3, 4, 5, 6]);

for item in stack.iter() {
    println!("{:?}", item);
}