枚举与不可变在D中

时间:2011-01-25 06:36:31

标签: enums immutability d

之间有什么区别
enum i = 2;
enum s = "Hello";

immutable i = 2;
immutable s = "Hello";

在D 2.0中?

2 个答案:

答案 0 :(得分:23)

enum是用户定义的类型,而不是变量。 enum e = 2;是一个 像enum : int { e = 2 }这样的短手(即匿名者) 枚举一名成员e),请参阅the documentation。 根据定义,匿名枚举的所有成员都被放入当前 范围。因此,e是放置在当前作用域中的类型成员 像一个literal。 另一方面, immutable i = 2;实际上会创建一个int类型的变量i

这种差异有几个后果:

  • enum e将没有内存位置,也没有地址(没有左值),因为 一个类型或其成员都没有地址。即你不能做某事 像auto ptr = &e;一样(就像你不能做auto ptr = &2;)。另一方面,immutable i是一个普通变量(只是不可变的)。
  • As discussed by Jonathan, 不可变变量可以在编译时或运行时初始化, 而必须知道一个类型(其所有成员定义类型) 编译时间。
  • 编译器可以简单地用e替换2的所有外观。对于i它 通常必须创建一个内存位置(虽然是一个优化编译器 可能有时可以避免这种情况)。出于这个原因,期间的工作量 预计enum的编译可能会略低一些 二进制有点小。
  • 阵列有惊人的差异。对于enum uint[2] E = [0, 1];和。{ immutable uint[2] I = [0, 1];访问enum,例如E[0],可以 比immutable数组慢几个数量级,例如I[0], 特别是当数组EI变大时。这是因为一个 immutable数组,它只是一个普通的数组查找,比如全局 变量。但对于enum,看起来每次都会创建数组 使用前的时间,例如在全局enum的函数内部(不要 问我,为什么,但编译器似乎只是简单地取代了外观 在这种情况下的价值也是如此)。我从来没有尝试,但会猜测 这同样适用于enum字符串和其他非平凡类型。

总结一下:当我使用编译时常量时,我​​通常会使用enum,除非 这些常量是数组,或者由于某些其他原因我需要一个内存位置。

答案 1 :(得分:8)

枚举总是在编译时初始化。因此,必须分配可通过CTFE(编译时功能评估)创建的值。

不可变变量可以在运行时初始化。如果不可变变量具有全局生命周期(因此它是模块变量或静态类或静态局部变量),那么它必须在编译时或在运行时使用静态构造函数初始化(尽管静态局部变量不能被赋予静态构造函数)。如果不可变变量是非静态局部变量,那么它在运行时初始化(但如果值是常量,则编译器可能会优化它并在编译时初始化它)。因此,您可以在运行时创建不可变的局部变量,这与枚举不同。

编辑:我忘记了另一个案例:不可变成员变量必须直接用CTFE初始化或用不可变构造函数初始化。如果使用CTFE直​​接初始化不可变成员varible,那么很明显这是在编译时完成的,而在不可变构造函数中初始化它是在运行时完成的。