问题描述
考虑这个愚蠢的枚举:
enum Number {
Rational {
numerator: i32,
denominator: std::num::NonZeroU32,
},
FixedPoint {
whole: i16,
fractional: u16,
},
}
Rational变量中的数据占用8个字节,而FixedPoint变量中的数据占用4个字节. Rational变体的字段必须为非零,因此我希望枚举布局规则将其用作鉴别符,零表示存在FixedPoint变体.
The data in the Rational variant takes up 8 bytes, and the data in the FixedPoint variant takes up 4 bytes. The Rational variant has a field which must be nonzero, so i would hope that the enum layout rules would use that as a discriminator, with zero indicating the presence of the FixedPoint variant.
但是,这:
fn main() {
println!("Number = {}", std::mem::size_of::<Number>(),);
}
打印:
Number = 12
因此,枚举为显式区分符留有空间,而不是利用非零字段的存在.
So, the enum gets space for an explicit discriminator, rather than exploiting the presence of the nonzero field.
为什么编译器不能使这个枚举变小?
Why isn't the compiler able to make this enum smaller?
推荐答案
尽管像Option<&T>
这样的简单情况,rustc中的布局计算器仍然不够聪明,无法优化带有多个非空变体的枚举的大小.
Although simple cases like Option<&T>
can be handled without reserving space for the tag, the layout calculator in rustc is still not clever enough to optimize the size of enums with multiple non-empty variants.
这是GitHub上的 issue#46213 .
This is issue #46213 on GitHub.
您询问的情况非常明确,但是在类似的情况下,枚举看起来应该被优化,但实际上并非如此,因为优化会排除采用内部变量的可能性.参考;例如,请参见为什么Rust只需要一个字节时,为什么使用两个字节来表示该枚举?
The case you ask about is pretty clear-cut, but there are similar cases where an enum looks like it should be optimized, but in fact can't be because the optimization would preclude taking internal references; for example, see Why does Rust use two bytes to represent this enum when only one is necessary?
这篇关于为什么这个Rust枚举不小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!