1个不稳定版本
| 0.1.0 | 2021年11月12日 |
|---|
#1355 in 数据结构
105KB
2K SLoC
重型炼金术 - 变化之黑魔法,包装后供您安全使用和享受。
hv-alchemy 是一组特性和类型,它维护了一个全局运行时注册表(目前静态不可用,但 linkme crate 可能会在某个时刻发挥作用),其中包含特例对象虚函数表和其他类型信息,如大小、对齐、析构函数等。它需要Rust nightly版以使用 ptr_metadata、unsize 和 arbitrary_self_types 功能。
此crate允许您做一些事情
- 在运行时询问:“我们知道此类型是否实现了此对象安全特例吗?”
- 将
dyn AlchemicalAny下的类型下推到具体的类型T - Dyn将
dyn AlchemicalAny下推到无大小的特例对象类型dyn Trait - 复制和克隆类型,而无需编译时
Copy和Clone约束(需要运行时注册的Copy和Clone实现) - 提取
Send、Sync、Copy和Clone约束,这些约束可以在编译时使用,并在运行时根据类型实现的特性有条件地访问,以根据特性特别化行为 - 在任何时间通过任何类型扩展
TypeTable(虚函数表注册表)以任何它已知静态实现的特性 - 通过将
Type<T>转换为Box<dyn AlchemicalAny>或任何其他为它实现的特性,在运行时访问“类型” - 将
Default::default函数指针项作为fn() -> T访问,其中 T 是实现Default的类型(在运行时检查,没有编译时Default绑定) - 给定一个
*const dyn AlchemicalAny,尝试使用dyn AlchemicalAny提供的类型表中的Layout来克隆它到一个新的分配
请勿滥用。 hv-alchemy 与 no_std 兼容,但需要 alloc。
注意事项
我们目前无法在编译时注册某些类型通过 Alchemy 实现的所有不同事物。因此,你基本上必须在你自己的 API 中提供某种类型的钩子(如果你依赖 Alchemy),这鼓励/提供了一种方法来将相关的特质对象添加到你所感兴趣的 TypeTable 中。例如 linkme 或目前损坏的 inventory crate 能够执行类似操作,但它们 不能在类型上普遍量化,因为这需要将一个 forall T. 绑定单形化为多个 Type::<T>::of().add::<...>() 调用,而 Rust 目前没有这样做的方法。
工作原理
Alchemy 保持一个全局静态的 HashMap,将 TypeId 映射到通过 Box::leak(在某个时刻这可能被切换到全局 Bump 区域或类似的东西)创建的 &'static TypeTable,这些 TypeTable 再次包含 HashMap,将 TypeId 映射到 &'static DynVtable;一个 DynVtable 代表某个特质对象 dyn SomeTrait 对于某个类型 SomeType 的 vtable。具体来说,如果你想检查某个对象是否实现了 fmt::Debug,Alchemy 的查找过程如下
- 获取对象的
TypeTable。如果我们试图动态转换一个特质对象dyn AlchemicalAny,只需调用其.type_table()方法即可。否则,如果知道T的静态类型(并且不需要静态fmt::Debug绑定),可以使用Type::<T>::of()- 如果我们使用
Type::<T>::of(),Alchemy 会获取TypeId的T并用它在全球注册表中查找其对应的TypeTable。如果没有找到,它会创建一个空的。
- 如果我们使用
- 获取
TypeId的dyn fmt::Debug,然后使用它来查找TypeTable的vtables映射中的相应DynVtable。 - 如果我们在那里找到一个
DynVtable,根据不变性,我们知道其实现类型将是我们要检查的对象的类型,而其特质对象类型将是dyn fmt::Debug。然后我们可以假设在原始引用/值上使用DynVtable::to_dyn_object_pointer是安全的,将其转换为&dyn fmt::Debug。或者,如果我们只想知道它是否实现了Debug,我们就有答案了。
许可证
根据您的选择,许可协议为以下之一
- Apache License, Version 2.0 (LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT 许可证 (LICENSE-MIT 或 https://open-source.org.cn/licenses/MIT)
。
贡献
除非您明确声明,否则根据 Apache-2.0 许可证定义的,您提交的任何有意包含在工作中的贡献,将按上述方式双许可,不附加任何额外条款或条件。
依赖项
~1.5MB
~19K SLoC