中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

iota在Go中的使用方法

發布時間:2021-04-29 13:43:21 來源:億速云 閱讀:335 作者:小新 欄目:編程語言

這篇文章將為大家詳細講解有關iota在Go中的使用方法,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

go是什么

golang是一種編譯語言,可以將代碼編譯為機器代碼,編譯后的二進制文件可以直接部署到目標機器而無需額外的依賴,所以golang的性能優于其他的解釋性語言,且可以在golang中使用goroutine來實現并發性,它提供了一個非常優雅的goroutine調度程序系統,可以很容易地生成數百萬個goroutine。

介紹

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

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

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.BTW, overuse of enums might mean that your methods do too much (it’s often better to have several separate methods, rather than one method that takes several flags which modify what it does), but if you have to use flags or type codes, enums are the way to go.

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

  • 當一個變量(尤其是方法參數) 只能從一小部分可能的值中取出一個時,理應使用枚舉。
    例如類型常量(合同狀態:永久、臨時工、學徒), 或者在做任務程序時,是立即執行還是延遲執行的標記。

  • 如果使用枚舉而不是整形,則會增加編譯時的檢查,避免錯誤無效值的傳入,記錄哪些值是合法使用的。

如何實現枚舉

iota 是 Go 中預聲明的一個特殊常量。它會被預聲明為0,但是它的值在編譯階段并非是固定的,當預聲明的 iota 出現在一個常量聲明中的時候,它的值在第n個常量描述中的值為n(從0開始)。所以它只在同類型多個常量聲明的情況下才顯得有意義。

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

package mainimport "fmt"type OrderStatus intconst (
  Cancelled OrderStatus = iota //訂單已取消 0  NoPay OrderStatus = iota //未支付  1  PendIng OrderStatus = iota // 未發貨 2  Delivered OrderStatus = iota // 已發貨 3  Received OrderStatus = iota // 已收貨 4)func main() {
  fmt.Println(Cancelled, NoPay) // 打印:0,1}

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

package mainimport "fmt"type OrderStatus intconst (
  Cancelled OrderStatus = iota //訂單已取消 0  NoPay //未支付 1  PendIng // 未發貨 2  Delivered // 已發貨 3  Received // 已收貨 4)func main() {
  fmt.Println(Cancelled, NoPay) // 打印:0,1}

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

package mainimport "fmt"type OrderStatus intconst (
  Cancelled OrderStatus = iota+1 //訂單已取消 1
  NoPay //未支付 2  PendIng // 未發貨 3  Delivered // 已發貨 4  Received // 已收貨 5)func main() {
  fmt.Println(Cancelled, NoPay) // 打印:1,2}

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

package mainimport "fmt"type OrderStatus intconst (
  Cancelled OrderStatus = iota+1 //訂單已取消 1
  NoPay //未支付 2  PendIng // 未發貨 3  Delivered // 已發貨 4  _
 Received // 已收貨 6)func main() {
  fmt.Println(Received) // 打印:6}

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

package mainimport "fmt"type OrderStatus intconst (
  Max = 5)const (
  Received OrderStatus = Max - iota // 已收貨  5  Delivered // 已發貨 4  PendIng // 未發貨 3  NoPay //未支付 2  Cancelled //訂單已取消 1)func main() {
  fmt.Println(Received,Delivered) // 打印:5,4}

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

const (
 mutexLocked = 1 << iota  //1<<0 mutexWoken               //1<<1 mutexStarving            //1<<2 mutexWaiterShift = iota  //3)func main() {
 fmt.Println("mutexLocked的值",mutexLocked) //打印:1 fmt.Println("mutexWoken的值",mutexWoken) //打印:2 fmt.Println("mutexStarving的值",mutexStarving) //打印:4 fmt.Println("mutexWaiterShift的值",mutexWaiterShift) // 打印:3}

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

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

package mainimport "fmt"const (
  Cancelled = "cancelled"  NoPay = "noPay"  PendIng = "pendIng"  Delivered = "delivered"  Received = "received")var OrderStatusMsg = map[string]string{
  Cancelled: "訂單已取消",
  NoPay:     "未付款",
  PendIng:   "未發貨",
  Delivered: "已發貨",
  Received:  "已收貨",}func main() {
  fmt.Println(OrderStatusMsg[Cancelled])}

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

package mainimport "fmt"const (
  Cancelled = 1  NoPay = 2  PendIng = 3  Delivered = 4  Received = 5)var OrderStatusMsg = map[int]string{
  Cancelled: "訂單已取消",
  NoPay:     "未付款",
  PendIng:   "未發貨",
  Delivered: "已發貨",
  Received:  "已收貨",}func main() {
  fmt.Println(OrderStatusMsg[Cancelled])}

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

  • 能保證一組常量的唯一性,人工定義的不能保證。

  • 可以為一組動作分享同一種行為。

  • 避免無效值。

  • 提高代碼閱讀性以及維護。

延伸

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

package mainimport (
 "fmt")type OrderStatus intconst (
  Cancelled OrderStatus = iota + 1 //訂單已取消 1  NoPay //未支付 2  PendIng // 未發貨 3  Delivered // 已發貨 4  Received // 已收貨 5)//公共行為 賦予類型 String() 函數,方便打印值含義func (order OrderStatus) String() string { return [...]string{"cancelled", "noPay", "pendIng", "delivered", "received"}[order-1]}//創建公共行為 賦予類型 int 函數 EnumIndex()func (order OrderStatus) EnumIndex() int { return int(order)}func main() {
 var order OrderStatus = Received
  fmt.Println(order.String())    // 打印:received
  fmt.Println(order.EnumIndex()) // 打印:5}

關于“iota在Go中的使用方法”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

腾冲县| 安徽省| 德庆县| 边坝县| 瓦房店市| 北宁市| 河东区| 图木舒克市| 荥经县| 石家庄市| 儋州市| 华亭县| 阳信县| 乌苏市| 巴林左旗| 济宁市| 庄河市| 陆丰市| 牙克石市| 昆明市| 定西市| 南木林县| 彝良县| 刚察县| 昌吉市| 呈贡县| 凉山| 旬邑县| 铁力市| 昔阳县| 中宁县| 南澳县| 桦南县| 会东县| 汾阳市| 卢湾区| 麟游县| 康平县| 上饶县| 凤庆县| 高台县|