本文介绍了为什么这个Rust枚举不小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑这个愚蠢的枚举:

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枚举不小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-13 02:01