之间有什么区别
enum i = 2;
enum s = "Hello";
和
immutable i = 2;
immutable s = "Hello";
在D 2.0中?
答案 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
是一个普通变量(只是不可变的)。e
替换2
的所有外观。对于i
它
通常必须创建一个内存位置(虽然是一个优化编译器
可能有时可以避免这种情况)。出于这个原因,期间的工作量
预计enum
的编译可能会略低一些
二进制有点小。enum uint[2] E = [0, 1];
和。{
immutable uint[2] I = [0, 1];
访问enum
,例如E[0]
,可以
比immutable
数组慢几个数量级,例如I[0]
,
特别是当数组E
和I
变大时。这是因为一个
immutable
数组,它只是一个普通的数组查找,比如全局
变量。但对于enum
,看起来每次都会创建数组
使用前的时间,例如在全局enum
的函数内部(不要
问我,为什么,但编译器似乎只是简单地取代了外观
在这种情况下的价值也是如此)。我从来没有尝试,但会猜测
这同样适用于enum
字符串和其他非平凡类型。总结一下:当我使用编译时常量时,我通常会使用enum
,除非
这些常量是数组,或者由于某些其他原因我需要一个内存位置。
答案 1 :(得分:8)
枚举总是在编译时初始化。因此,必须分配可通过CTFE(编译时功能评估)创建的值。
不可变变量可以在运行时初始化。如果不可变变量具有全局生命周期(因此它是模块变量或静态类或静态局部变量),那么它必须在编译时或在运行时使用静态构造函数初始化(尽管静态局部变量不能被赋予静态构造函数)。如果不可变变量是非静态局部变量,那么它在运行时初始化(但如果值是常量,则编译器可能会优化它并在编译时初始化它)。因此,您可以在运行时创建不可变的局部变量,这与枚举不同。
编辑:我忘记了另一个案例:不可变成员变量必须直接用CTFE初始化或用不可变构造函数初始化。如果使用CTFE直接初始化不可变成员varible,那么很明显这是在编译时完成的,而在不可变构造函数中初始化它是在运行时完成的。