您好,登錄后才能下訂單哦!
本篇內容主要講解“Go中怎么正確使用對枚舉”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Go中怎么正確使用對枚舉”吧!
枚舉是強類型編程語言中的一種類型,由一組名稱和值組成。通常用來在編程語言中充當常量的標識符。
沒毛病,我們也確實是這樣使用的。比如上學的時候,經常寫c的小玩具代碼,c標準里面提供了enum關鍵字,寫起來比較直白,使用的時候和struct類似,需要enum week這樣寫,c里面默認枚舉值是從0開始,int類型,其實c里面就是把枚舉當做int類型來用的。
#include<stdio.h> enum week{Mon, Tue, Wed, Thur, Fri, Sat, Sun}; int main() { enum week day; // 需要加 enum 關鍵字 day = Wed; printf("%d",day); // 輸出 2 int i; for (i=Mon; i<=Sun; i++){ // 可以直接把枚舉類型賦值給int類型 printf("%d ", i); // 輸出 0,1,2,3,4,5,6 } return 0; }
上面的例子沒問題,在初始化的時候,枚舉值默認情況下,編譯器會從分配0開始的值,例如上面的Mon=0,Tue=1…,但是也會想不按照編譯器的默認分配方式,由我自己分配,那怎么寫呢,看下面的例子:
#include <stdio.h> enum day {sunday = 1, monday, tuesday = 5, wednesday, thursday = 10, friday, saturday}; int main() { printf("%d %d %d %d %d %d %d", sunday, monday, tuesday, wednesday, thursday, friday, saturday); // 輸出1 2 5 6 10 11 12 return 0; }
也就是說,枚舉里面可以按任何順序將值分配給某個名稱。所有未分配的名稱都會把值作為前一個名稱的值加一。
其實,定義幾個常量的事,是不是用宏這個東西更好呢,比如這么寫
#define sunday 0 #define monday 1 #define tuesday 2
但是老師說了,盡量別用宏,不是說宏不好,宏也好,編譯器替換,沒有運行期啥事,多快啊,但是有幾個問題:
1)宏沒有作用域一說 2)枚舉是類型安全的
扯的有點遠了,現在回來看看Go里面的枚舉怎么寫。當然也很簡單了,官方教導我們這么寫:
type ByteSize float64 const ( _ = iota KB ByteSize = 1 << (10 * iota) MB GB )
Go里面更簡潔了,直接把enum關鍵字去掉了,其實從Go的角度看,枚舉不就是常量么,搞這么多語法糖干嘛,Go里面提供了一個關鍵字iota可以實現常量的遞增,同時也支持手動賦值,iota和手動賦值結合起來,就可以實現類似c里面的效果
const ( A0 = iota A1 = iota A2 = iota ) fmt.Println(A0, A1, A2) // "0 1 2"
可以 簡寫成這樣
const ( A0 = iota A1 A2 )
也可以從1開始
const ( A1 = iota + 1 A2 A3 ) fmt.Println(A1, A2, A3) // "1 2 3"
或者跳過某個值
const ( C1 = iota + 1 _ C3 C4 ) fmt.Println(C1, C3, C4) // "1 3 4"
看到這里你或許有個疑問,這里的枚舉其實就是常量么,那怎么寫是字符串類型的枚舉呢,你可能會說,當然是用字符串常量了。但是那只是字符串常量了,沒有枚舉的性質。我可能想要的是一種字符串到值的枚舉類型。思考再三,看我這種寫法是否可以:
步驟一:創建一個新的int類型
步驟二:使用iota表示值
步驟三:給這個新的類型一個String的方法
type Direction int const ( North Direction = iota East South West ) func (d Direction) String() string { return [...]string{"North", "East", "South", "West"}[d] }
使用的時候
var d Direction = North fmt.Print(d) switch d { case North: fmt.Println(" goes up.") case South: fmt.Println(" goes down.") default: fmt.Println(" stays put.") }
當然還有一種方法,比較stupid
type weekday string func (w weekday) isWeekday() weekday { return w } type Weekday interface { isWeekday() weekday } const ( Monday = weekday("Monday") Tuesday = weekday("Tuesday") Wendsday = weekday("Wendsday") Thursday = weekday("Thursday") Friday = weekday("Friday") Saturday = weekday("Saturday") Sunday = weekday("Sunday") ) // 使用 func main() { var d1 = weekday.Monday var d2 = weekday.Tuesday fmt.Println(d1, d2, d1 == d2, d1 == weekday.Monday) }
如果使用struct表示枚舉,那其實還可以使用反射的方式,比如下面這樣寫:
import ( "reflect" ) type weekday struct { Monday, Tuesday, Wendsday, Thursday, Friday, Saturday, Sunday int } func (c weekday) Get(id string) int { vo := reflect.ValueOf(c) typeVo := vo.Type() for i := 0; i < vo.NumField(); i++ { if typeVo.Field(i).Name == id { return vo.Field(i).Interface().(int) } } return 0 } var weekdayEnum = weekday { Monday: 1, Tuesday: 2, Wendsday: 3, Thursday: 4, Friday: 5, Saturday: 6, Sunday: 7 }
到此,相信大家對“Go中怎么正確使用對枚舉”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。