为什么Nil会增加一个枚举的大小,而不会增加另一个枚举的大小?如何为Rust枚举分配内存? [英] Why does Nil increase one enum size but not another? How is memory allocated for Rust enums?
问题描述
如果我定义以下枚举,则Nil不会增加枚举的大小:
If I define the following enums, Nil does not increase the size of the enum:
use std::mem::size_of;
enum Foo {
Cons(~char)
}
enum Bar {
Cons(~char),
Nil
}
println!("{}", size_of::<Foo>());
println!("{}", size_of::<Bar>());
// -> 4
// -> 4
另一方面:
enum Foo {
Cons(char)
}
enum Foo {
Cons(char),
Nil
}
收益:
// -> 4
// -> 8
当我定义一个枚举时会发生什么?如何为这些结构分配内存?
What is happening when I define an enum? How is memory being allocated for these structures?
推荐答案
一种简单的枚举方法是为其最大变体的内容以及描述符添加足够的空间.这是一个标准的带有标记的联合.
A naive approach to enums is to allocate enough space for the contents of its largest variant, plus a descriminant. This is a standard tagged union.
铁锈比这更聪明. (这可能会更聪明,但目前还不行.)它知道给定~T
时,内存位置不能至少有一个值:零.因此,在像enum { Cons(~T), Nil }
这样的情况下,它可以将其优化为一个单词,而内存中的任何非零值表示Cons(~T)
,而内存中的任何非零值表示Nil
.
Rust is a little cleverer than this. (It could be a lot cleverer, but it is not at present.) It knows that given a ~T
, there is at least one value that that memory location cannot be: zero. And so in a case like your enum { Cons(~T), Nil }
, it is able to optimise it down to one word, with any non-zero value in memory meaning Cons(~T)
and a zero value in memory meaning Nil
.
处理char
时,不会发生这种优化:零是有效的代码点.碰巧,char
被定义为Unicode代码点,因此实际上可以在该空间中优化变体,最后有很多备用位(Unicode字符).只需21位,因此在32位空间中,我们有11个备用位).这证明了Rust的枚举判别优化目前还不是特别聪明.
When you deal with char
, that optimisation cannot occur: zero is a valid codepoint. As it happens, char
is defined as being a Unicode code-point, so it would actually be possible to optimise the variant into that space, there being plenty of spare bits at the end (Unicode character only needs 21 bits, so in a 32-bit space we have eleven spare bits). This is a demonstration of the fact that Rust's enum discriminant optimisation is not especially clever at present.
这篇关于为什么Nil会增加一个枚举的大小,而不会增加另一个枚举的大小?如何为Rust枚举分配内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!