用新类型包装 NonZeroUsize

apt*_*002 1 rust

我读过Option<NonZeroUsize>它只占用一个单词的内存,例如usize.

我想将它与新类型的成语结合起来。我想定义struct Pos(NonZeroUsize),以便编译器防止我将 aPos与任何其他混淆NonZeroUsize,但不会丢失紧凑表示。

会只Option<Pos>占用一个单词的内存吗?

Frx*_*rem 5

默认情况下,虽然编译器可能能够优化 的大小Option<Pos>,但没有#[repr]注释的类型无法保证内存布局:

默认表示
没有repr属性的名义类型具有默认表示。非正式地,这种表示也称为rust表示。

此表示不保证数据布局。

但是,您可以指定#[repr(transparent)]强制Pos具有与其单一字段相同的布局:

#[repr(transparent)]
struct Pos(NonZeroUsize);
Run Code Online (Sandbox Code Playgroud)

transparent表示
透明表示只能在一个结构或使用具有一个单一的变体的枚举使用:

  • 具有非零大小的单个字段,以及
  • 任意数量的大小为 0 且对齐为 1 的字段(例如 PhantomData)。

具有此表示形式的结构和枚举与单个非零大小的字段具有相同的布局和 ABI。

然后Option<Pos>将始终NonZeroUsize与此列表中的每个点 5 和 7具有相同的大小:

Option表示
Rust 保证优化以下类型T,使其与Option<T>具有相同的大小T

  1. Box<U>
  2. &U
  3. &mut U
  4. fn, extern "C" fn
  5. num::NonZero*
  6. ptr::NonNull<U>
  7. #[repr(transparent)] 围绕此列表中的一种类型构建结构。