成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Go 真的有枚舉嗎?

開發 后端
代碼抽象于現實。程序與生活中關于枚舉的概念是相通的:枚舉代表一個對象所有可能取值的集合。

[[437193]]

本文轉載自微信公眾號「Golang技術分享」,作者機器鈴砍菜刀。轉載本文請聯系Golang技術分享公眾號。

Go 中有枚舉嗎?這是一個模棱兩可的問題。有人說它有,有人說它沒有。

什么是枚舉

代碼抽象于現實。程序與生活中關于枚舉的概念是相通的:枚舉代表一個對象所有可能取值的集合。例如,表示星期的 SUNDAY、MONDAY、TUESDAY、WEDNESDAY、THURSDAY、FRIDAY、SATURDAY 就是一組枚舉值。

實際上,我們可以將 Go 中所有原始類型視為一種枚舉。例如 bool 類型可以被認為是一個只能為 true 或 false 的枚舉;byte 類型是 0 至 255 的枚舉;指針是 32 位或 64 位地址空間所有可能的內存地址的枚舉。

在例如 Python、Java、C 等語言中,一般都會有enum關鍵字或類提供于開發者實現枚舉。

通用偽代碼可表達如下

  1. enum 枚舉名{ 
  2.     標識符①[=整型常數], 
  3.     標識符②[=整型常數], 
  4.     ... 
  5.     標識符N[=整型常數], 
  6. }枚舉變量; 

Go 沒有enum關鍵字。但我們可以觀察枚舉的特征:同一組枚舉值在定義后不應被改變;枚舉值對應的數據類型應該相同;枚舉值是有限的;枚舉值與其含義是一一對應的。

根據以上特征,在 Go 中可通過const與 iota關鍵字來實現枚舉的訴求。

iota

const用于定義常量,它們在編譯期創建,在運行時不能被修改。且僅有布爾型、數字型(整數型、浮點型和復數)和字符串型能被定義為常量。

常量聲明格式如下

  1. const identifier [type] = value 

而 iota 是常量計數器,它在遇到 const 關鍵字時,就被重置為 0。當 const 中每增一行常量聲明(包括空白標識符_),iota 計數將加1。

  1. const ( 
  2.  A int = iota   // 0 
  3.  _            
  4.  B              // 2 
  5.  C              // 3 
  6.  D              // 4 
  7.  
  8. const ( 
  9.  E int = iota   // 0 
  10.  F              // 1 

Go 枚舉實現

有了iota的參與,在 Go 中想要枚舉星期值,我們可以如下定義

  1. type Weekday int 
  2.  
  3. const ( 
  4.  _ Weekday = iota // ignore first value by assigning to blank identifier 
  5.  Sunday 
  6.  Monday 
  7.  Tuesday 
  8.  Wednesday 
  9.  Thursday 
  10.  Friday 
  11.  Saturday 

在使用枚舉值過程中,往往有輸出打印的需求

  1. fmt.Println(Sunday, Monday)  // 1 2 

但原始的結果很不直觀,它不能反映出枚舉值背后的含義。我們需要為 Weekday 對象定義輸出。

  1. func (w Weekday) String() string { 
  2.  return [...]string{"Sunday""Monday""Tuesday""Wednesday""Thursday""Friday""Saturday"}[w-1] 

在 Go 中,我們可以為任意自定義類型綁定String()方法,使其按照String()方法中定義的格式進行打印。

  1. func main() { 
  2.  var day = Monday 
  3.  switch day { 
  4.  case Monday, Tuesday, Wednesday, Thursday, Friday: 
  5.   fmt.Printf("今天是%s,加油!打工人"day
  6.  case Saturday, Sunday: 
  7.   fmt.Printf("今天是%s,好好休息!打工人"day
  8.  default
  9.   fmt.Println("不存在的一天"
  10.  } 

執行結果

  1. 今天是Monday,加油!打工人 

Go 枚舉實現的不足

上述方案看似已經實現了枚舉功能,但其實存在一些問題。

首先,由于 iota 基于 int 類型,這意味著在程序中,任何整數都可以轉為枚舉類型(這也是為何我們上文switch的case 中會有default分支),但這并不是我們想要的。

  1. func main() { 
  2.  fakeNum := 8 
  3.  day := Weekday(fakeNum) 
  4.  fmt.Println(day
  5.  
  6. # go run main.go 
  7. %!v(PANIC=String method: runtime error: index out of range [7] with length 7) 

那善于思考的讀者就會想到,既然 int 不行,那我們可以采用字符串常量來表示枚舉值啊。但這個方案同樣存在上述的問題,而且相較于使用 int 比較,當比較字符串時,需要付出額外的性能成本。

另外,我們對于枚舉還有一個很重要的訴求,就是枚舉。對應于 Go 循環表達式,枚舉迭代的期望是這樣

  1. for i, day := range Weekday { 
  2.  ... 

但顯然,現在的代碼方案滿足不了這種訴求。

總結

本文討論了 Go 目前通過 iota 關鍵字實現枚舉的做法,但這種方式并沒有實現完整的枚舉功能。在官方 issue 19814 中提出了 Go 中應該增加 enum 關鍵字的提案,感興趣的讀者可以詳細查看。

關于 Go 中的枚舉實現,你有不一樣的觀點嗎,歡迎留言討論。

參考

 

proposal: spec: add typed enum support: https://github.com/golang/go/issues/19814

 

責任編輯:武曉燕 來源: Golang技術分享
相關推薦

2023-12-26 08:17:04

Go框架Go 語言

2013-08-07 14:30:33

微信5.0

2012-07-03 15:04:22

程序員

2021-05-18 11:14:55

人臉識別人工智能技術

2012-04-16 10:15:13

JQuery插件開發

2024-04-07 00:00:05

事務Java開發

2022-01-05 12:03:48

MySQL索引數據

2022-08-15 08:06:49

Go語言類型

2023-04-21 10:33:42

2022-05-11 09:04:50

Go函數數組

2010-03-03 14:35:49

Android智能手機

2019-10-11 14:43:55

Windows電腦硬盤分區

2020-03-13 14:45:14

Java枚舉代碼

2019-06-14 14:48:41

多云云計算云平臺

2020-01-15 10:17:41

Kubernetes容器負載均衡

2020-03-04 10:13:55

Kubernetes容器開發

2020-04-17 14:25:22

Kubernetes應用程序軟件開發

2022-07-26 00:00:22

HTAP系統數據庫

2014-04-17 16:42:03

DevOps

2020-10-21 10:53:33

Google壟斷法瀏覽器
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美一级片 | 九九热免费视频在线观看 | 欧美日韩国产一区二区三区 | 欧美精品a∨在线观看不卡 国产精品久久国产精品 | 韩国av电影网 | 精品在线播放 | a级黄色片视频 | 国产线视频精品免费观看视频 | 国产精品成人品 | 亚洲精品久久久久久国产精华液 | 久久精品一级 | 日日夜夜天天综合 | 日本三级在线 | 欧美日韩精品一区二区三区四区 | 成年人在线 | 日韩一区中文字幕 | 天天干天天操天天看 | 久久久国产精品 | 国产日韩欧美一区 | 99精品欧美一区二区三区综合在线 | av一区二区三区四区 | 国产一级毛片精品完整视频版 | 亚洲高清成人 | 成人免费看黄网站在线观看 | 91av视频在线观看 | 国产男女视频网站 | 中文字幕专区 | 久草中文在线 | 亚洲成人一区 | 91精品国产综合久久久久久漫画 | 999国产视频 | 亚洲国产成人精品女人久久久野战 | 在线精品国产 | 欧美一区二区三区四区视频 | 天天综合网91| 在线一区视频 | 久久人体视频 | 亚洲成av人片在线观看 | 精品视频一区二区三区 | 久久综合久 | 中文字幕一区在线 |