2014-12-05 63 views
4

我的理解是,enum就像C中的union,系统将分配enum中最大的数据类型。为什么枚举需要额外的内存大小?

enum E1 { 
    DblVal1(f64), 
} 

enum E2 { 
    DblVal1(f64), 
    DblVal2(f64), 
    DblVal3(f64), 
    DblVal4(f64), 
} 

fn main() { 
    println!("Size is {}", std::mem::size_of::<E1>()); 
    println!("Size is {}", std::mem::size_of::<E2>()); 
} 

为什么E1占用8个字节的预期,但E2占用16个字节?

回答

7

在Rust中,与C不同,enum s是tagged unions。也就是说,enum知道它拥有哪个值。所以8个字节是不够的,因为标签没有空间。

+6

对于8字节的增加:这是简单地约存储器对齐。大部分空间都没有使用。这只是填充。 – sellibitze 2014-12-06 01:04:37

+5

我很高兴看到Rust枚举的内存布局。任何人都知道那篇文章? – RajV 2014-12-08 21:26:17

2

作为第一个近似值,您可以假设枚举是其变体最大值的大小加上判别式值以知道它是哪个变体,并且四舍五入以高效对齐。对齐取决于平台。

这并非总是如此;有些类型是“聪明的”,包装更紧张,如Option<&T>。你的E1是另一个例子;它不需要需要判别式,因为只有一个可能的值。

枚举的实际内存布局是未定义的,取决于编译器的奇想。如果您的变体没有值的枚举,则可以使用repr属性来指定总大小以及布局。

您可以使用Rust中的联合。这些做而不是有一个标记/判别式值,并且是最大变体的大小(可能还会添加对齐)。作为交换,这些是不安全的阅读,因为你不能静态确定它是什么变体。

参见: