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