为什么Nil增加一个枚举大小而不是另一个?如何为Rust枚举分配内存?

o_o*_*o-- 3 memory-management rust data-structures

如果我定义以下枚举,Nil不会增加枚举的大小:

  use std::mem::size_of;

  enum Foo {
    Cons(~char)
  }

  enum Bar {
    Cons(~char),
    Nil
  }

  println!("{}", size_of::<Foo>());
  println!("{}", size_of::<Bar>());

  // -> 4
  // -> 4
Run Code Online (Sandbox Code Playgroud)

另一方面:

  enum Foo {
    Cons(char)
  }

  enum Foo {
    Cons(char),
    Nil
  }
Run Code Online (Sandbox Code Playgroud)

产量:

  // -> 4
  // -> 8
Run Code Online (Sandbox Code Playgroud)

定义枚举时发生了什么?如何为这些结构分配内存?

Chr*_*gan 7

对枚举的一种天真的方法是为其最大变体的内容分配足够的空间,以及判别.这是标准的标记联合.

Rust比这更聪明一点.(它可能更加聪明,但目前还不是.)它知道给定a ~T,至少有一个值,即内存位置不能为零:零.因此在像你这样的情况下enum { Cons(~T), Nil },它能够将其优化为一个单词,在内存意义上具有任何非零值,在内存意义上Cons(~T)具有零值Nil.

处理时char,不会发生优化:零是有效的代码点.碰巧的是,char被定义为一个Unicode码点,所以它实际上是可能的变体优化成空间,有被大量在末端备用比特(Unicode字符只需要21个比特,所以在32位位空间我们有11个备用位).这表明Rust的枚举判别优化目前并不是特别聪明.