6

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

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

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

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

4

1 回答 1

5

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

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

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

由于data结构可以具有不同的大小,因此您的表示不支持 O(1) 随机访问,而这个支持。有关详细信息,请参阅此博客文章

示例,改编自文档:

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);
}
于 2020-03-18T15:09:31.870 回答