Go語言現階段沒有列舉型別,但是可以使用 const 常數配合上一節《Go語言常數》中介紹的 iota 來模擬列舉型別,請看下面的程式碼:
type Weapon int
const (
Arrow Weapon = iota // 開始生成列舉值, 預設為0
Shuriken
SniperRifle
Rifle
Blower
)
// 輸出所有列舉值
fmt.Println(Arrow, Shuriken, SniperRifle, Rifle, Blower)
// 使用列舉型別並賦初值
var weapon Weapon = Blower
fmt.Println(weapon)
程式碼輸出如下:
0 1 2 3 4
4
程式碼說明如下:
第 1 行中,將 int 定義為 Weapon 型別,就像列舉型別的本質是一個 int 型別一樣。當然,某些情況下,如果需要 int32 和 int64 的列舉,也是可以的。
第 4 行中,將常數 Arrow 的型別標識為 Weapon,這樣標識後,const 下方的常數可以使用 Weapon 作為預設型別。該行使用 iota 進行常數值自動生成,iota 的起始值為 0,一般情況下也是建議列舉從 0 開始,讓每個列舉型別都有一個空值,方便業務和邏輯的靈活使用。
一個 const 宣告內的每一行常數宣告,將會自動套用前面的 iota 格式,並自動增加,類似於電子試算表中單元格自動填充的效果,只需要建立好單元格之間的變化關係,拖動右下方的小點就可以自動生成單元格的值。
當然,iota 不僅可以生成每次增加 1 的列舉值。還可以利用 iota 來做一些強大的列舉常數值生成器。下面的程式碼可以方便的生成標誌位常數:
const (
FlagNone = 1 << iota
FlagRed
FlagGreen
FlagBlue
)
fmt.Printf("%d %d %dn", FlagRed, FlagGreen, FlagBlue)
fmt.Printf("%b %b %bn", FlagRed, FlagGreen, FlagBlue)
程式碼輸出如下:
2 4 8
10 100 1000
在程式碼中編寫一些標誌位時,我們往往手動編寫常數值,常數值特別多時,很容易重複或者寫錯,因此,使用 ioto 自動生成更加方便。
程式碼說明如下:
-
第 2 行中 iota 使用了一個移位元運算,每次將上一次的值左移一位(二進位制位),以得出每一位的常數值。
-
第 8 行,將 3 個列舉按照常數輸出,分別輸出 2、4、8,都是將 1 每次左移一位的結果。
-
第 9 行,將列舉值按二進位制格式輸出,可以清晰地看到每一位的變化。
將列舉值轉換為字串
列舉在 C# 中是一個獨立的型別,可以通過列舉值獲取該值對應的字串。例如,C# 中 Week 列舉值 Monday 為 1,那麼可以通過 Week.Monday.ToString() 函數獲得 Monday 字串。
Go語言中也可以實現這一功能,程式碼如下所示:
轉換字串:
package main
import "fmt"
// 宣告晶片型別
type ChipType int
const (
None ChipType = iota
CPU // 中央處理器
GPU // 圖形處理器
)
func (c ChipType) String() string {
switch c {
case None:
return "None"
case CPU:
return "CPU"
case GPU:
return "GPU"
}
return "N/A"
}
func main() {
// 輸出CPU的值並以整型格式顯示
fmt.Printf("%s %d", CPU, CPU)
}
執行結果:
CPU 1
程式碼說明如下:
-
第 6 行,將 int 宣告為 ChipType 晶片型別。
-
第 9 行,將 const 裡定義的常數值設為 ChipType 型別,且從 0 開始,每行值加 1。
-
第 14 行,定義 ChipType 型別的方法 String(),返回值為字串型別。
-
第 15~22 行,使用 switch 語句判斷當前的 ChitType 型別的值,返回對應的字串。
-
第 30 行,按整型的格式輸出 CPU 的值。
String() 方法的 ChipType 在使用上和普通的常數沒有區別。當這個型別需要顯示為字串時,Go語言會自動尋找 String() 方法並進行呼叫。