Как я могу создать список принадлежащих черт объектов, не выделяя каждый элемент в куче отдельно? - PullRequest
6 голосов
/ 18 марта 2020

Я хочу собственный список объектов черты 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() и iter().

1 Ответ

5 голосов
/ 18 марта 2020

Ящик dynstack делает то, что вы хотите. Он основан на представлении жирных указателей, которые являются объектами черты, и это представление теоретически может измениться однажды.

Хотя он решает проблему избегания выделения кучи для каждого объекта, его представление в памяти отличается: вместо простого списка в основном два списка:

  • [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);
}
...