4 个版本 (稳定版)
新 1.0.2 | 2024 年 8 月 17 日 |
---|---|
1.0.0 | 2024 年 5 月 14 日 |
0.0.1 | 2024 年 5 月 13 日 |
#22 在 无标准库
475,811 每月下载量
在 1,307 个 Crates 中使用 (直接使用 3 个)
13KB
126 行
常量 TypeId
和非静态 TypeId
常量 TypeId
此 crate 提供 ConstTypeId
,它类似于 core::any::TypeId
,但可以在稳定 Rust 的 const 中构建。 (标准库的 TypeId 只在 nightly 中可以用于 const 构建;关于此问题的跟踪问题是 rust#77125。)
能够在 const 中构建 ConstTypeId
,使其适用于依赖于静态提升的使用场景
use std::fmt::{self, Debug, Display};
use std::ptr;
use typeid::ConstTypeId;
pub struct ObjectVTable {
type_id: ConstTypeId,
drop_in_place: unsafe fn(*mut ()),
display: unsafe fn(*const (), &mut fmt::Formatter) -> fmt::Result,
debug: unsafe fn(*const (), &mut fmt::Formatter) -> fmt::Result,
}
impl ObjectVTable {
pub const fn new<T: Display + Debug>() -> &'static Self {
&ObjectVTable {
type_id: const { ConstTypeId::of::<T>() },
drop_in_place: |ptr| unsafe { ptr::drop_in_place(ptr.cast::<T>()) },
display: |ptr, f| unsafe { Display::fmt(&*ptr.cast::<T>(), f) },
debug: |ptr, f| unsafe { Debug::fmt(&*ptr.cast::<T>(), f) },
}
}
}
以及在关联常量中
use typeid::ConstTypeId;
pub trait GetTypeId {
const TYPEID: ConstTypeId;
}
impl<T: 'static> GetTypeId for T {
const TYPEID: ConstTypeId = ConstTypeId::of::<Self>();
}
非静态 TypeId
此 crate 提供 typeid::of
,它接受一个任意非静态类型 T
并生成将 T
中所有生命周期替换为 'static
(除了在 trait 对象中找到的更高秩生命周期之外)的类型 TypeId
。
例如,如果 T
是 &'b dyn for<'a> Trait<'a, 'c>
,则 typeid::of::<T>()
生成 &'static dyn for<'a> Trait<'a, 'static>
的 TypeId。
应该很明显,与标准库中的 TypeId 不同,typeid::of::<A>() == typeid::of::<B>()
并不意味着 A
和 B
是同一类型。然而,有一种常见特殊情况,这种行为正是所需要的。如果
A
是一个任意的非 'static 类型参数,并且B
是 'static,并且- 所有与
B
具有相同 id 的类型也是 'static
则 typeid::of::<A>() == typeid::of::<B>()
保证 A
和 B
是同一类型。
use core::any::TypeId;
use core::slice;
pub fn example<T>(slice: &[T]) {
// T is arbitrary and non-'static.
if typeid::of::<T>() == TypeId::of::<u8>() {
// T is definitely u8
let bytes = unsafe { slice::from_raw_parts(slice.as_ptr().cast(), slice.len()) };
process_bytes(bytes);
} else {
for t in slice {
process(t);
}
}
}
fn process<T>(_: &T) {/* ... */}
fn process_bytes(_: &[u8]) {/* ... */}
许可证
根据您的选择,在 Apache 许可证 2.0 版 或 MIT 许可证 下许可。除非您明确声明,否则根据 Apache-2.0 许可证定义的,您有意提交以包含在此软件包中的任何贡献,应如上所述双重许可,不得附加任何额外的条款或条件。