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

為什么我們需要在 Go 中使用 Iota

開發 后端
Go 語言實際上沒有直接支持枚舉的關鍵字。一般我們都是通過 const + iota 實現枚舉的能力。

[[395811]]

本文轉載自微信公眾號「吳親強的深夜食堂」,作者吳親庫里。轉載本文請聯系吳親強的深夜食堂公眾號。  

介紹

Go 語言實際上沒有直接支持枚舉的關鍵字。一般我們都是通過 const + iota 實現枚舉的能力。

有人要問了,為什么一定要使用枚舉呢?stackoverflow[1] 上有一個高贊的回答,如下:

You should always use enums when a variable (especially a method parameter) can only take one out of a small set of possible values. Examples would be things like type constants (contract status: "permanent", "temp", "apprentice"), or flags ("execute now", "defer execution").

If you use enums instead of integers (or String codes), you increase compile-time checking and avoid errors from passing in invalid constants, and you document which values are legal to use.

簡單翻譯一下, 兩點很重要。

  • 當一個變量(尤其是方法參數) 只能從一小部分可能的值中取出一個時,理應使用枚舉。例如類型常量(合同狀態:永久、臨時工、學徒), 或者在做任務程序時,是立即執行還是延遲執行的標記。
  • 如果使用枚舉而不是整形,則會增加編譯時的檢查,避免錯誤無效值的傳入,記錄哪些值是合法使用的。

如何實現枚舉

iota 是 Go 中預聲明的一個特殊常量。它會被預聲明為0,但是它的值在編譯階段并非是固定的,當預聲明的 iota 出現在一個常量聲明中,它的值在第n個常量描述中的值為n(從0開始)。

比如,大家都或多或少了解電商系統。其中的訂單模塊一定會涉及到訂單狀態的流轉。那么這時候,我們一般可以這樣定義:

  1. package main 
  2.  
  3. import "fmt" 
  4.  
  5. type OrderStatus int 
  6.  
  7. const ( 
  8.   Cancelled OrderStatus = iota //訂單已取消 0 
  9.   NoPay OrderStatus = iota //未支付 1 
  10.   PendIng OrderStatus = iota // 未發貨 2 
  11.   Delivered OrderStatus = iota // 已發貨 3 
  12.   Received OrderStatus = iota // 已收貨 4 
  13.  
  14. func main() { 
  15.   fmt.Println(Cancelled, NoPay) // 打印:0,1 

當然,這樣看著好麻煩。其實,其他常量可以重復上一行 iota 表達式,我們可以改成這樣。

  1. package main 
  2.  
  3. import "fmt" 
  4.  
  5. type OrderStatus int 
  6.  
  7. const ( 
  8.   Cancelled OrderStatus = iota //訂單已取消 0 
  9.   NoPay //未支付 1 
  10.   PendIng // 未發貨 2 
  11.   Delivered // 已發貨 3 
  12.   Received // 已收貨 4 
  13.  
  14. func main() { 
  15.   fmt.Println(Cancelled, NoPay) // 打印:0,1 

有人會用 0 的值來表示狀態嗎?一般都不會,我們想以1開頭,那么可以這樣。

  1. package main 
  2.  
  3. import "fmt" 
  4.  
  5. type OrderStatus int 
  6.  
  7. const ( 
  8.   Cancelled OrderStatus = iota+1 //訂單已取消 1 
  9.   NoPay //未支付 2 
  10.   PendIng // 未發貨 3 
  11.   Delivered // 已發貨 4 
  12.   Received // 已收貨 5 
  13.  
  14. func main() { 
  15.   fmt.Println(Cancelled, NoPay) // 打印:1,2 

我們還想在 Delivered 后跳過一個數字,才是 Received 的值,也就是 Received=6,那么可以借助 _ 符號。

  1. package main 
  2.  
  3. import "fmt" 
  4.  
  5. type OrderStatus int 
  6.  
  7. const ( 
  8.   Cancelled OrderStatus = iota+1 //訂單已取消 1 
  9.   NoPay //未支付 2 
  10.   PendIng // 未發貨 3 
  11.   Delivered // 已發貨 4 
  12.   _ 
  13.   Received // 已收貨 6 
  14.  
  15. func main() { 
  16.   fmt.Println(Received) // 打印:6 

順著來可以,倒著當然也行。

  1. package main 
  2.  
  3. import "fmt" 
  4.  
  5. type OrderStatus int 
  6.  
  7. const ( 
  8.   Max = 5 
  9.  
  10. const ( 
  11.   Received OrderStatus = Max - iota // 已收貨 5 
  12.   Delivered // 已發貨 4 
  13.   PendIng // 未發貨 3 
  14. NoPay //未支付 2 
  15.   Cancelled //訂單已取消 1 
  16.  
  17. func main() { 
  18.   fmt.Println(Received,Delivered) // 打印:5,4 

還可以使用位運算,比如在 go 源碼中的包 sync 中的鎖上面有這么一段定義代碼。

  1. const ( 
  2.     mutexLocked = 1 << iota  //1<<0 
  3.     mutexWoken //1<<1 
  4.     mutexStarving //1<<2 
  5.     mutexWaiterShift = iota  //3 
  6.  
  7.  
  8. func main() { 
  9.     fmt.Println("mutexLocked的值",mutexLocked) //打印:1 
  10.     fmt.Println("mutexWoken的值",mutexWoken) //打?。? 
  11.     fmt.Println("mutexStarving的值",mutexStarving) //打?。? 
  12.     fmt.Println("mutexWaiterShift的值",mutexWaiterShift) // 打?。? 

也許有人平常是直接定義常量值或者用字符串來表示的。

比如,上面這些我完全可以用 string 來表示,我還真見過用字符串來表示訂單狀態的。

  1. package main 
  2.  
  3. import "fmt" 
  4.  
  5. const ( 
  6.   Cancelled = "cancelled" 
  7.   NoPay = "noPay" 
  8.   PendIng = "pendIng" 
  9.   Delivered = "delivered" 
  10.   Received = "received" 
  11.  
  12. var OrderStatusMsg = map[string]string{ 
  13.   Cancelled: "訂單已取消"
  14.   NoPay: "未付款"
  15.   PendIng: "未發貨"
  16.   Delivered: "已發貨"
  17.   Received: "已收貨"
  18.  
  19. func main() { 
  20.   fmt.Println(OrderStatusMsg[Cancelled]) 

或者直接定義整形常量值。

  1. package main 
  2.  
  3. import "fmt" 
  4.  
  5. const ( 
  6.   Cancelled = 1 
  7.   NoPay = 2 
  8.   PendIng = 3 
  9.   Delivered = 4 
  10.   Received = 5 
  11.  
  12. var OrderStatusMsg = map[int]string{ 
  13.   Cancelled: "訂單已取消"
  14.   NoPay: "未付款"
  15.   PendIng: "未發貨"
  16.   Delivered: "已發貨"
  17.   Received: "已收貨"
  18.  
  19. func main() { 
  20.   fmt.Println(OrderStatusMsg[Cancelled]) 

其實上述兩種都可以,但是相比之下使用 iota 更有優勢。

  • 能保證一組常量的唯一性,人工定義的不能保證。
  • 可以為一組動作分享同一種行為。
  • 避免無效值。
  • 提高代碼閱讀性以及維護。

延伸

按照上面我們所演示的,最后我們可以這樣操作。

  1. package main 
  2.  
  3. import ( 
  4.   "fmt" 
  5.  
  6. type OrderStatus int 
  7.  
  8. const ( 
  9.   Cancelled OrderStatus = iota + 1 //訂單已取消 1 
  10.   NoPay //未支付 2 
  11.   PendIng // 未發貨 3 
  12.   Delivered // 已發貨 4 
  13.   Received // 已收貨 5 
  14.  
  15. //公共行為 賦予類型 String() 函數,方便打印值含義 
  16. func (order OrderStatus) String() string { 
  17.   return [...]string{"cancelled""noPay""pendIng""delivered""received"}[order-1] 
  18.  
  19. //創建公共行為 賦予類型 int 函數 EnumIndex() 
  20. func (order OrderStatus) EnumIndex() int { 
  21.   return int(order
  22.  
  23. func main() { 
  24.   var order OrderStatus = Received 
  25.   fmt.Println(order.String()) // 打印:received 
  26.   fmt.Println(order.EnumIndex()) // 打印:5 

總結

這篇文章主要介紹了 Golang 中對 iota 的使用介紹,以及我們為什么要使用它。

不知道大家平常對于此類場景用的什么招數,歡迎下方留言交流。

附錄

[1]

https://stackoverflow.com/questions/4709175/what-are-enums-and-why-are-they-useful

https://levelup.gitconnected.com/implementing-enums-in-golang-9537c433d6e2

https://medium.com/qvault/how-and-why-to-write-enums-in-go-9c1a25649df0

 

責任編輯:武曉燕 來源: 吳親強的深夜食堂
相關推薦

2022-06-02 08:48:39

Go枚舉器Iota

2023-11-30 09:00:00

TypeScript開發

2023-04-13 11:05:10

5G網絡無線技術

2022-12-01 14:43:56

物聯網智慧城市

2020-04-06 14:45:22

云計算邊緣計算網絡

2025-06-24 02:00:00

5G-A運營商基站

2019-08-05 08:42:37

物聯網IOT技術

2018-09-14 18:00:29

無損網絡

2023-09-05 09:49:03

2022-08-26 08:00:19

企業架構IT

2016-09-27 21:25:08

Go語言Ken Thompso

2016-01-20 09:54:51

微服務架構設計SOA

2012-08-13 09:15:54

Go開發語言編程語言

2015-08-03 10:40:45

動效設計優勢

2015-11-11 13:35:15

2021-05-24 11:30:49

智能建筑IOT物聯網

2021-04-09 09:55:55

DockerGoLinux

2022-07-21 08:00:00

人工智能開發機器學習

2022-01-03 08:06:15

函數Go數據

2011-06-08 10:30:08

MongoDB
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久精品福利视频 | 亚洲综合婷婷 | 日本精品视频 | 一区二区三区日韩精品 | 欧美不卡在线 | 91视频网址 | 国产精品精品视频一区二区三区 | 日本综合在线观看 | 在线一区二区三区 | 夜夜骑首页 | 色天堂影院 | 日韩一二三区视频 | 99国产精品久久久 | 国产传媒视频在线观看 | 久久久久久久国产 | 日本在线中文 | 日韩手机视频 | 午夜成人在线视频 | 在线中文字幕国产 | 成年无码av片在线 | 亚洲国产高清高潮精品美女 | 青青草视频免费观看 | 国产在线中文字幕 | 亚洲欧美第一视频 | 免费精品久久久久久中文字幕 | 久久草在线视频 | 中文字幕蜜臀av | 欧美国产中文 | 欧美日韩国产一区二区三区 | 日韩欧美国产精品一区二区三区 | 精品九九| 国产精品一区久久久 | jav成人av免费播放 | 久久久精 | 日韩激情网 | 久久精品亚洲一区二区三区浴池 | 99久久99热这里只有精品 | 日韩在线精品视频 | 天天综合成人网 | 国产毛片视频 | 这里只有精品999 |