#traits #trait-object #no-std #memory-block #no-alloc #fixed-size

nightly no-std sized-dst

基于静态内存的动态大小类型的所有者容器

1 个不稳定版本

0.1.0 2024 年 8 月 11 日

#1049Rust 模式

Download history 100/week @ 2024-08-10

每月 100 次下载

MIT/Apache

33KB
586

sized-dst

此包提供了 Dst,这是一个动态大小类型(DST)的所有者容器,由静态内存支持。主要用例是 无需堆分配的所有权 trait 对象。您可以将其视为 Box 的堆栈版本。

由于它依赖于 Unsize 和指针元数据,此包目前需要 nightly

sized_dst::Dst 的布局由 DST 元数据(对于 trait 对象,这是 vtable 指针)和存储实际对象的固定内存块组成。这允许它在栈上或静态变量中完全存在。其内存块的尺寸和对齐方式由泛型参数指定,因此 sized_dst::Dst 只能存储适合其内存块的对象。如果对象不满足尺寸或对齐要求,sized_dst::Dst 的构造函数将发出 编译时 错误。

use sized_dst::{Dst, max_size};

trait Draw {
    fn draw(&self);
}

struct Button {
    height: u32,
    width: u32,
    name: &'static str,
}
impl Draw for Button {
    fn draw(&self) { /* draw the button */ }
}

struct Checkbox {
    on: bool,
}
impl Draw for Checkbox {
    fn draw(&self) { /* draw the checkbox */ }
}

struct Text(&'static str);
impl Draw for Text {
    fn draw(&self) { /* draw the text */ }
}

struct Blob([u8; 100]);
impl Draw for Blob {
    fn draw(&self) { /* draw the blob */ }
}

fn main() {
    // Each Dst stores a `dyn Draw` up to a fixed capacity, which is set via `max_size` to
    // the size of the biggest trait object we're using.
    let drawables: &[Dst<dyn Draw, { max_size!(Checkbox, Text, Button) }>] = &[
        Dst::new(Checkbox { on: true }),
        Dst::new(Text("lorem ipsum")),
        Dst::new(Button {
            height: 20,
            width: 20,
            name: "PANIC BUTTON",
        }),
        // Dst::new(Blob([0; 100]))    This would not compile, because Blob doesn't fit in Dst
    ];

    // Perform dynamic dispatch over the Draw trait
    for d in drawables {
        d.draw();
    }
}

Box 相比,Dst 不需要间接或分配,使其更缓存友好,并且可用于没有分配器的环境中。作为交换,Dst 只能存储固定大小的对象,使其不如 Box 灵活。从某种意义上说,Dst 在枚举和boxed trait 对象之间提供了一个折衷方案。

可选功能

  • std:启用 std 特性的实现。

依赖关系

~29KB