Q
枚举VS在d
13
A
回答
23
enum
是用户定义的类型,而不是变量。enum 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, 不可变的变量可以在编译时或运行时, 而类型(及其所有成员定义的类型)必须在 编译时是已知被初始化。
- 编译器可以简单地用
2
替换e
的所有外观。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
除非 那些常量数组或者我需要一些其他的原因,一个内存位置。
8
枚举总是在编译时初始化。因此,他们必须为分配可以通过CTFE(编译时功能评估)创建的值。
不可变变量可以在运行时初始化。如果一个不可变变量具有全局生存期(因此它是模块变量或静态类或静态局部变量),那么它必须在编译时或在运行时使用静态构造函数初始化(尽管静态局部变量不能被分配一个静态构造函数)。如果一个不可变的变量是一个非静态的局部变量,那么它在运行时初始化(尽管如果该值是一个常量,那么编译器可能会优化它并在编译时初始化它)。因此,您可以在运行时创建不可变的局部变量,与枚举不同。
编辑:我忘了另一种情况:不可变的成员变量必须用CTFE直接初始化或用不可变的构造函数初始化。如果使用CTFE直接初始化一个不可变成员变量,那么显然这是在编译时完成的,而在一个不可变构造函数中初始化它是在运行时完成的。
相关问题
- 1. 枚举VS查找表VS枚举反射VS State模式
- 2. 常量枚举(tsc.js VS typescript.js)
- 3. LINQ vs常规枚举
- 4. NoSql:枚举vs字符串
- 5. 枚举vs int标志?
- 6. 常量与枚举中的D
- 7. 在枚举中枚举
- 8. 在枚举语句中枚举mysql枚举
- 9. 如何在保持枚举枚举
- 10. Java在枚举中的枚举
- 11. 在枚举枚举中调用.Distinct()
- 12. 枚举在Hibernate中,坚持为枚举
- 13. 带枚举的MySQL枚举
- 14. Java枚举找到枚举
- 15. Java类枚举枚举类
- 16. 转换枚举来枚举
- 17. 重新枚举枚举
- 18. 类型代码vs枚举重构?
- 19. 在编译时完全枚举D维数组的索引
- 20. 在枚举java
- 21. 枚举在C++
- 22. 枚举在VB.NET
- 23. 如何在枚举类型仅在运行时知道枚举枚举?
- 24. 枚举
- 25. 枚举
- 26. 枚举
- 27. 枚举
- 28. 枚举
- 29. 当枚举值不在枚举中时赋予枚举的默认值
- 30. 枚举在Java中
是的。因为这不是一个有效的CTFE表达式。您目前不能在CTFE上使用`new`。它还没有那么先进。 – 2011-01-25 08:01:34
等等,但是我该如何创建一个不可变的类的实例? – Mehrdad 2011-01-25 08:05:44