枚举 – 为什么当只需要一个时,Rust会使用两个字节来表示这个枚举?

它看起来很聪明,只能为A使用一个字节,但不够聪明,不能使用一个字节用于B,即使只有8 * 8 = 64种可能性.有没有办法哄Rust来解决这个问题,还是我必须手动实现更紧凑的布局?

Playground link.

#![allow(dead_code)]

enum A {
    L,
    UL,
    U,
    UR,
    R,
    DR,
    D,
    DL,
}

enum B {
    C(A, A),
}

fn main() {
    println!("{:?}", std::mem::size_of::<A>()); // prints 1
    println!("{:?}", std::mem::size_of::<B>()); // prints 2
}
最佳答案
两个字节都是保留借用struct成员的能力所必需的.

Rust中的类型不是一组理想的值:它有一个数据布局,描述了值的存储方式.管理该语言的一个“规则”是将一个类型放在一个struct或enum中不会改变它的数据布局:它在另一个类型中具有与它独立的相同的布局,这允许你引用struct成员和将它们与任何其他参考文献互换使用.*

在满足此约束的同时,无法将两个As放入一个字节,因为A的大小是一个整数字节 – 即使使用repr(打包),也无法处理字节的一部分.未使用的位只是保持未使用状态(除非可以通过利基填充来重新利用它们来存储枚举标记).

*好吧,repr(打包)实际上可以使这不真实. Taking a reference to a packed field can cause undefined behavior,即使是安全的代码!

转载注明原文:枚举 – 为什么当只需要一个时,Rust会使用两个字节来表示这个枚举? - 代码日志