3 个版本 (破坏性更新)
0.3.0 | 2024年5月9日 |
---|---|
0.2.0 | 2024年5月7日 |
0.1.0 | 2024年5月4日 |
#11 in #non
被 zonbi 使用
4KB
65 行
Zonbi
这是一个实验,旨在使非 'static
类型可以进行类型擦除。
工作原理
通过使用 #[derive(Zonbi)]
,类型将获得一个实现,该实现返回一个所有生命周期都被给定生命周期替换的类型版本。手动实现是不安全的,因为用户必须保证 Casted
类型与实现者相同。
这被用于 ZonbiId
,它是 TypeId
的包装器,与内部值不同,它为非 'static
类型提供了额外的行为定义。 ZonbiId
对于每个类型都是唯一的,不包括 生命周期。底层,它只是使用 Zonbi
特性来获取类型的 'static
版本,并获取其 TypeId
。
要在一个 box 中持有这样的类型擦除值,例如,你可以创建一个 zonbi Z
的 Cage<'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.0
和MIT
依赖关系
~290–750KB
~18K SLoC