日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
為什么我們需要在Go中使用Iota

本文轉(zhuǎn)載自微信公眾號(hào)「吳親強(qiáng)的深夜食堂」,作者吳親庫(kù)里。轉(zhuǎn)載本文請(qǐng)聯(lián)系吳親強(qiáng)的深夜食堂公眾號(hào)。  

文登ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書(shū)未來(lái)市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)公司的ssl證書(shū)銷(xiāo)售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18980820575(備注:SSL證書(shū)合作)期待與您的合作!

介紹

Go 語(yǔ)言實(shí)際上沒(méi)有直接支持枚舉的關(guān)鍵字。一般我們都是通過(guò) const + iota 實(shí)現(xiàn)枚舉的能力。

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

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.

簡(jiǎn)單翻譯一下, 兩點(diǎn)很重要。

  • 當(dāng)一個(gè)變量(尤其是方法參數(shù)) 只能從一小部分可能的值中取出一個(gè)時(shí),理應(yīng)使用枚舉。例如類(lèi)型常量(合同狀態(tài):永久、臨時(shí)工、學(xué)徒), 或者在做任務(wù)程序時(shí),是立即執(zhí)行還是延遲執(zhí)行的標(biāo)記。
  • 如果使用枚舉而不是整形,則會(huì)增加編譯時(shí)的檢查,避免錯(cuò)誤無(wú)效值的傳入,記錄哪些值是合法使用的。

如何實(shí)現(xiàn)枚舉

iota 是 Go 中預(yù)聲明的一個(gè)特殊常量。它會(huì)被預(yù)聲明為0,但是它的值在編譯階段并非是固定的,當(dāng)預(yù)聲明的 iota 出現(xiàn)在一個(gè)常量聲明中,它的值在第n個(gè)常量描述中的值為n(從0開(kāi)始)。

比如,大家都或多或少了解電商系統(tǒng)。其中的訂單模塊一定會(huì)涉及到訂單狀態(tài)的流轉(zhuǎn)。那么這時(shí)候,我們一般可以這樣定義:

  
 
 
  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 // 未發(fā)貨 2 
  11.   Delivered OrderStatus = iota // 已發(fā)貨 3 
  12.   Received OrderStatus = iota // 已收貨 4 
  13.  
  14. func main() { 
  15.   fmt.Println(Cancelled, NoPay) // 打印:0,1 

當(dāng)然,這樣看著好麻煩。其實(shí),其他常量可以重復(fù)上一行 iota 表達(dá)式,我們可以改成這樣。

  
 
 
  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 // 未發(fā)貨 2 
  11.   Delivered // 已發(fā)貨 3 
  12.   Received // 已收貨 4 
  13.  
  14. func main() { 
  15.   fmt.Println(Cancelled, NoPay) // 打印:0,1 

有人會(huì)用 0 的值來(lái)表示狀態(tài)嗎?一般都不會(huì),我們想以1開(kāi)頭,那么可以這樣。

  
 
 
  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 // 未發(fā)貨 3 
  11.   Delivered // 已發(fā)貨 4 
  12.   Received // 已收貨 5 
  13.  
  14. func main() { 
  15.   fmt.Println(Cancelled, NoPay) // 打印:1,2 

我們還想在 Delivered 后跳過(guò)一個(gè)數(shù)字,才是 Received 的值,也就是 Received=6,那么可以借助 _ 符號(hào)。

  
 
 
  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 // 未發(fā)貨 3 
  11.   Delivered // 已發(fā)貨 4 
  12.   _ 
  13.   Received // 已收貨 6 
  14.  
  15. func main() { 
  16.   fmt.Println(Received) // 打印:6 

順著來(lái)可以,倒著當(dāng)然也行。

  
 
 
  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 // 已發(fā)貨 4 
  13.   PendIng // 未發(fā)貨 3 
  14. NoPay //未支付 2 
  15.   Cancelled //訂單已取消 1 
  16.  
  17. func main() { 
  18.   fmt.Println(Received,Delivered) // 打印:5,4 

還可以使用位運(yùn)算,比如在 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) //打?。? 
  10.     fmt.Println("mutexWoken的值",mutexWoken) //打印:2 
  11.     fmt.Println("mutexStarving的值",mutexStarving) //打?。? 
  12.     fmt.Println("mutexWaiterShift的值",mutexWaiterShift) // 打?。? 

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

比如,上面這些我完全可以用 string 來(lái)表示,我還真見(jiàn)過(guò)用字符串來(lái)表示訂單狀態(tài)的。

  
 
 
  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: "未發(fā)貨", 
  16.   Delivered: "已發(fā)貨", 
  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: "未發(fā)貨", 
  16.   Delivered: "已發(fā)貨", 
  17.   Received: "已收貨", 
  18.  
  19. func main() { 
  20.   fmt.Println(OrderStatusMsg[Cancelled]) 

其實(shí)上述兩種都可以,但是相比之下使用 iota 更有優(yōu)勢(shì)。

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

延伸

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

  
 
 
  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 // 未發(fā)貨 3 
  12.   Delivered // 已發(fā)貨 4 
  13.   Received // 已收貨 5 
  14.  
  15. //公共行為 賦予類(lèi)型 String() 函數(shù),方便打印值含義 
  16. func (order OrderStatus) String() string { 
  17.   return [...]string{"cancelled", "noPay", "pendIng", "delivered", "received"}[order-1] 
  18.  
  19. //創(chuàng)建公共行為 賦予類(lèi)型 int 函數(shù) 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 

總結(jié)

這篇文章主要介紹了 Golang 中對(duì) iota 的使用介紹,以及我們?yōu)槭裁匆褂盟?/p>

不知道大家平常對(duì)于此類(lèi)場(chǎng)景用的什么招數(shù),歡迎下方留言交流。

附錄

[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


分享名稱:為什么我們需要在Go中使用Iota
本文來(lái)源:http://www.dlmjj.cn/article/coeeies.html