即使只有8 * 8 = 64的可能性,它似乎也足够聪明,仅对A使用一个字节,而对于对B使用一个字节则不够聪明。有什么办法哄骗Rust解决这个问题,还是我必须手动实现更紧凑的布局?
#![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
}
答案 0 :(得分:9)
两个字节对于保持借用结构成员的能力都是必需的。
Rust中的类型不是理想的值集:它具有数据布局,该布局描述了如何存储值。控制该语言的“规则”之一是将类型放入struct
或enum
内不会更改其数据布局:它在另一种类型内的布局与独立类型的布局相同,这允许你采取引用结构成员和与任何其它参考可互换地使用它们。*
在满足此约束的情况下,无法将两个A
装入一个字节,因为A
的大小是一个完整的字节-甚至无法寻址一个字节的一部分与repr(packed)
。未使用的位只是保持未使用(除非可以通过利基填充将它们重新用于存储枚举标签)。
*好吧,repr(packed)
实际上可以使这个不真实的。 Taking a reference to a packed field can cause undefined behavior,即使是安全密码!