为什么这个 Rust 枚举没有变小?

Why is this Rust enum not smaller?

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

enum Number {
    Rational {
        numerator: i32,
        denominator: std::num::NonZeroU32,
    },
    FixedPoint {
        whole: i16,
        fractional: u16,
    },
}

Rational变体占8字节,FixedPoint变体占4字节。 Rational 变体有一个必须为非零的字段,因此我希望枚举布局规则将其用作鉴别器,零表示存在 FixedPoint 变体。

然而,这:

fn main() {
    println!("Number = {}", std::mem::size_of::<Number>(),);
}

打印:

Number = 12

因此,枚举得到 space 作为显式鉴别器,而不是利用非零字段的存在。

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

虽然像Option<&T>这样的简单情况,rustc 中的布局计算器仍然不够聪明,无法优化具有多个非空变体的枚举的大小。

这是 GitHub 上的 issue #46213

你问的情况很明确,但也有类似的情况,枚举看起来应该优化,但实际上不可能,因为优化将排除采用内部参考;例如,参见