<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
哈嘍,大家好,我是asong。列舉是一種很重要的資料型別,在java、C語言等主流程式語言中都支援了列舉型別,但是在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型別會存在以下隱患:
於是乎我們就想到用常數字元來表示,程式碼就變成了這樣:
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語言沒有提供列舉型別,但是我們也可以根據Go語言的兩個特性:常數和定義新型別來實現列舉,方法總比困難多嗎,開源庫是優秀的,我們往往可以從高手那裡裡學習很多,記住,請永遠保持一個學徒之心;
到此這篇關於Go專案怎麼使用列舉的文章就介紹到這了,更多相關Go 列舉內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45