2017-04-01 34 views
2

我在看這段代碼:爲什麼使用枚舉二進制移

/** 
* Bitmask of states 
*/ 
export const enum ViewState { 
    FirstCheck = 1 << 0,  // result is 1 
    ChecksEnabled = 1 << 1, // result is 2 
    Errored = 1 << 2,   // result is 4 
    Destroyed = 1 << 3  // result is 8 
} 

我不明白爲什麼不能簡單地指定有整數結果或整數0,1,2,3。有人有什麼主意嗎?

+1

因爲它更容易閱讀(這對我來說無論如何也顯然是作者)。隨着這個列表變得更加容易(對於人類來說)添加第16個元素並使用'1 << 15',然後找出結果值將是什麼。所以只是一個偏好問題。 – Igor

+0

@Igor,謝謝你的建議,但是在代碼中,它始終是'ViewState.Destroyed',所以它沒有什麼關係 –

+3

如果意圖是將多個值進行或運算(這是典型的位掩碼),那麼它**不會影響到那裏的數字。 –

回答

5

因爲它更容易閱讀(這對我來說無論如何,顯然也是作者)。隨着此列表的增長(對於人類來說)更容易添加第16個元素並使用1,然後找出結果值將是什麼。所以只是一個偏好問題

使用班次的原因是你可以將多個狀態組合成一個單一的值。示例:值6將是ErroredChecksEnabled

var combined = ViewState.ChecksEnabled | ViewState.Errored; 

var isChecksEnabled = (combined & ViewState.ChecksEnabled) == ViewState.ChecksEnabled; 
// or 
var isChecksEnabled = !!(combined & ViewState.ChecksEnabled); 
+0

謝謝,請你舉個例子嗎? –

+0

@Maximus - 這裏有一個如何組合的例子,以及如何檢查是否有值的例子。也許這就是你想要的? – Igor

+1

是的,明白了,非常感謝您的解釋。 ViewState中的所有值都只有一個位集,這就是爲什麼我得到1,2,4,8..16,32 ...等等。 –

3

這枚舉模擬了四個標誌的想法,每個標誌都可以是/ true/one或off/false/zero。您可以通過將所需值邏輯「或」來將枚舉設置爲一個值。例如:

z = ViewState.FirstCheck | ViewState.ChecksEnabled 

稍後在代碼中,你可以通過logicall相互獨立的檢查這些價值觀和-ING與要檢查一個值:

if (z & ViewState.FirstCheck) { 
    do_something(); 
} 

if (z & ViewState.ChecksEnabled) { 
    do_something_else(); 
} 

最簡單的方法,以確保你可以將枚舉值分解成一個明確的,明確的標記集合,將單獨的值作爲二的冪。

+1

感謝您的解釋,upvoted –