Enums 为什么这个锈点不小?

Enums 为什么这个锈点不小?,enums,rust,memory-layout,Enums,Rust,Memory Layout,考虑一下这个愚蠢的枚举: enum Number { Rational { numerator: i32, denominator: std::num::NonZeroU32, }, FixedPoint { whole: i16, fractional: u16, }, } Rational变量中的数据占用8个字节,而FixedPoint变量中的数据占用4个字节。Rational变量有一个字段必须

考虑一下这个愚蠢的枚举:

enum Number {
    Rational {
        numerator: i32,
        denominator: std::num::NonZeroU32,
    },
    FixedPoint {
        whole: i16,
        fractional: u16,
    },
}
Rational变量中的数据占用8个字节,而FixedPoint变量中的数据占用4个字节。Rational变量有一个字段必须是非零的,所以我希望enum布局规则将使用它作为一个鉴别器,零表示存在FixedPoint变量

然而,这:

fn main() {
    println!("Number = {}", std::mem::size_of::<Number>(),);
}
因此,枚举为显式鉴别器获取空间,而不是利用非零字段的存在


为什么编译器不能使这个枚举变小?

尽管像
Option
这样的简单情况,但rustc中的布局计算器仍然不够聪明,无法优化具有多个非空变量的枚举的大小

这是在GitHub上


您询问的情况非常明确,但也有类似的情况,枚举看起来应该进行优化,但实际上不能,因为优化将排除获取内部引用;例如,请参见前面讨论过的

。我想答案是编译器还不够聪明@DenysSéguret:布局应该是
Rational::numerator
FixedPoint
重叠,并且
Rational::denominator
与任何东西都不重叠。如果在
Rational::densor
处占用的内存为0,则它是
固定点
,否则它是
Rational
。相关:这是。几年前,我自己尝试过实现它,但没有成功。然而,与此同时,rustc的情况发生了变化,我认为现在可能更容易了。
Number = 12