#zero #type-state #sized #zero-sized #unsigned-int

no-std zst

零大小泛型类型,相关类型暴露类型参数

3个版本

0.1.2 2022年7月17日
0.1.1 2022年2月18日
0.1.0 2022年2月14日

#1863Rust模式


nalgebra_latex 中使用

MIT/Apache

9KB
52

零大小泛型类型,相关类型暴露类型参数

将类型本身而不是其值表示出来的一个好方法是使用零大小类型,通常简称为ZST。程序员可以有一个枚举,其变体存储相应的ZST(以及隐含的、可能或可能不被优化的枚举区分符);然后枚举的大小将不依赖于表示的类型的大小。

在撰写本文时,没有标准的包装器可以获取表示类型的ZST。最接近的替代方案是core::marker::PhantomData,然而,PhantomData的语义是不必要地丰富,并且具有不希望的通用性/易用性之间的权衡,对于这种情况的次要用途

注意:更精确地说,所需的代码ZST<T>泛型ZST 新类型接近于PhantomData<*const T>

由于ZST<T>必须表示T,因此希望访问相关类型是很自然的。这可以通过TheAssocTy关联类型来实现。

示例

use zst::ZST;
use core::mem::{size_of, size_of_val};

// Repr is necessary to ensure the size of the discriminant
#[repr(u8)]
enum PrimUnsignedIntKinds {
    U8(ZST<u8>),
    U16(ZST<u16>),
    U32(ZST<u32>),
    U64(ZST<u64>),
    U128(ZST<u128>),
    Usize(ZST<usize>),
}

assert_eq!(size_of::<ZST<u16>>(), 0);
assert_eq!(
    size_of_val(&PrimUnsignedIntKinds::U16(ZST::<u16>::default())),
    size_of::<u8>()
);
// Since the ZST<T> is 1-aligned (#[repr(align(1))]), the following is guaranteed to hold
assert_eq!(
    size_of::<PrimUnsignedIntKinds>(),
    size_of::<core::mem::Discriminant<PrimUnsignedIntKinds>>()
);

注意:如文档所述,core::mem::Discriminant不透明数据类型。类似地,任何 enum 的数据布局为了性能考虑而相当模糊。您可以在 不安全代码指南参考 中了解详细信息。

依赖项

~1.5MB
~36K SLoC