为什么 Rust 在只需要一个字节的情况下使用两个字节来表示这个枚举?

Why does Rust use two bytes to represent this enum when only one is necessary?

看起来很聪明,只用一个字节给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
}

这两个字节都是保留借用结构成员的能力所必需的。

Rust 中的类型不是一组理想的值:它有一个数据布局,描述了值的存储方式。管理语言的 "rules" 之一是将类型放入 structenum 不会改变其数据布局:它在另一种类型中具有与独立时相同的布局,这允许您引用结构成员并将它们与任何其他引用互换使用。*

无法在满足此约束的同时将两个 A 放入一个字节中,因为 A 的大小是一个完整的字节——您无法寻址一个字节的一部分,即使 repr(packed)。未使用的位保持未使用状态(除非它们可以通过利基填充重新用于存储枚举标签)。

*嗯,repr(packed) 实际上可以使这不真实。 Taking a reference to a packed field can cause undefined behavior,即使是安全代码!