3 个版本 (破坏性更新)

0.3.0 2024年5月9日
0.2.0 2024年5月7日
0.1.0 2024年5月4日

#11 in #non


zonbi 使用

MIT/Apache

4KB
65

Zonbi

这是一个实验,旨在使非 'static 类型可以进行类型擦除。

工作原理

通过使用 #[derive(Zonbi)],类型将获得一个实现,该实现返回一个所有生命周期都被给定生命周期替换的类型版本。手动实现是不安全的,因为用户必须保证 Casted 类型与实现者相同。

这被用于 ZonbiId,它是 TypeId 的包装器,与内部值不同,它为非 'static 类型提供了额外的行为定义。 ZonbiId 对于每个类型都是唯一的,不包括 生命周期。底层,它只是使用 Zonbi 特性来获取类型的 'static 版本,并获取其 TypeId

要在一个 box 中持有这样的类型擦除值,例如,你可以创建一个 zonbi ZCage<'life, Z>,然后在一个具有相关最小生命周期的 dyn AnyZonbi<'life> 中持有它。每个至少存活了 'life 的 zonbi 都可以向上转换为这个特性,并可以向下转换回它,所有生命周期都是这个最小 'life

示例

use zonbi::*;

#[derive(Zonbi)]
struct MyStruct<'a> {
    val: &'a NonCopyI32,
}

type_map(&NonCopyI32(42));

fn type_map<'a>(a: &'a NonCopyI32) {
    let my_struct = MyStruct { val: a };

    let mut type_map: HashMap<ZonbiId, Box<dyn AnyZonbi<'a>>> = HashMap::new();
    let id = ZonbiId::of::<MyStruct>();

    type_map.insert(id, Box::new(Cage::new(my_struct)));

    let r: &MyStruct<'a> = type_map[&id].downcast_ref::<MyStruct<'a>>().unwrap();
    assert_eq!(r.val, &NonCopyI32(42));
}

这是 type_map 示例 的简化片段。

许可证

双许可协议下,遵循Apache-2.0MIT

依赖关系

~290–750KB
~18K SLoC