您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“Go項目如何使用枚舉”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Go項目如何使用枚舉”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
我們以java語言為例子,在JDK1.5之前沒有枚舉類型,我們通常會使用int常量來表示枚舉,一般使用如下:
public static final int COLOR_RED = 1; public static final int COLOR_BLUE = 2; public static final int COLOR_GREEN = 3;
使用int類型會存在以下隱患:
不具備安全性,聲明時如果沒有使用final就會造成值被篡改的風險;
語義不夠明確,打印int型數字并不知道其具體含義
于是乎我們就想到用常量字符來表示,代碼就變成了這樣:
public static final String COLOR_RED = "RED"; public static final String COLOR_BLUE = "BLUE"; public static final String COLOR_GREEN = "GREEN";
這樣也同樣存在問題,因為我們使用的常量字符,那么有些程序猿不按套路出牌就可以使用字符串的值進行比較,這樣的代碼會被不斷模仿變得越來越多的,然后屎山就出現了;
所以我們迫切需要枚舉類型的出現來起到約束的作用,假設使用一個枚舉類型做入參,枚舉類型就可以限定沙雕用戶不按套路傳參,這樣就可以懟他了,哈哈~;
使用枚舉的代碼就可以變成這樣,傳了枚舉之外的類型都不可以了;
public class EnumClass { public static void main(String [] args){ Color color = Color.RED; convert(color); System.out.println(color.name()); } public static void convert(Color c){ System.out.println(c.name()); } } enum Color{ RED,BLUE,GREEN; }
Go語言就沒有枚舉類型,我們該使用什么方法來替代呢?
枚舉通常是一組相關的常量集合,Go語言中有提供常量類型,所以我們可以使用常量來聲明枚舉,但也同樣會遇到上述的問題,起不到約束的作用,所以為了起到約束我們可以使用Go語言另外一個知識點 -- 類型定義,Go語言中可以使用type關鍵字定義不同的類型,我們可以為整型、浮點型、字符型等定義新的類型,新的類型與原類型轉換需要顯式轉換,這樣在一定程度上也起到了約束的作用,我們就可以用Go語言實現如下枚舉:
type OrderStatus int const ( CREATE OrderStatus = iota + 1 PAID DELIVERING COMPLETED CANCELLED ) func main() { a := 100 IsCreated(a) }
上面的代碼就會報錯:
./main.go:19:12: cannot use a (variable of type int) as type OrderStatus in argument to IsCreated
定義新的類型可以起到約束作用,比如我們要檢查狀態機,入參限定了必須是OrderStatus類型,如果是int類型就會報錯。
上面我們的枚舉實現方式只能獲取枚舉值,獲取不到其映射的字面意思,所以我們可以優化一下,實現String方法,使用官方提供的cmd/string來快速實現,代碼如下:
//go:generate stringer -type=OrderStatus type OrderStatus int const ( CREATE OrderStatus = iota + 1 PAID DELIVERING COMPLETED CANCELLED )
執行命令go generate ./...生成orderstatus_string.go文件:
import "strconv" func _() { // An "invalid array index" compiler error signifies that the constant values have changed. // Re-run the stringer command to generate them again. var x [1]struct{} _ = x[CREATE-1] _ = x[PAID-2] _ = x[DELIVERING-3] _ = x[COMPLETED-4] _ = x[CANCELLED-5] } const _OrderStatus_name = "CREATEPAIDDELIVERINGCOMPLETEDCANCELLED" var _OrderStatus_index = [...]uint8{0, 6, 10, 20, 29, 38} func (i OrderStatus) String() string { i -= 1 if i < 0 || i >= OrderStatus(len(_OrderStatus_index)-1) { return "OrderStatus(" + strconv.FormatInt(int64(i+1), 10) + ")" } return _OrderStatus_name[_OrderStatus_index[i]:_OrderStatus_index[i+1]] }
Go語言使用protobuf會生成對應的枚舉代碼,我們發現其中也是使用定義新的類型的方式來實現的,然后在封裝一些方法,我們來賞析一下protobuf生成的枚舉代碼:
const ( CREATED OrderStatus = 1 PAID OrderStatus = 2 CANCELED OrderStatus = 3 ) var OrderStatus_name = map[int32]string{ 1: "CREATED", 2: "PAID", 3: "CANCELED", } var OrderStatus_value = map[string]int32{ "CREATED": 1, "PAID": 2, "CANCELED": 3, } func (x OrderStatus) Enum() *OrderStatus { p := new(OrderStatus) *p = x return p } func (x OrderStatus) String() string { return proto.EnumName(OrderStatus_name, int32(x)) } func (x *OrderStatus) UnmarshalJSON(data []byte) error { value, err := proto.UnmarshalJSONEnum(OrderStatus_value, data, "OrderStatus") if err != nil { return err } *x = OrderStatus(value) return nil }
讀到這里,這篇“Go項目如何使用枚舉”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。