2014-12-05 57 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中的聯合。這些做而不是有一個標記/判別式值,並且是最大變體的大小(可能還會添加對齊)。作爲交換,這些是不安全的閱讀,因爲你不能靜態確定它是什麼變體。

參見: