本篇内容主要讲解“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&hellip;,但是也会想不按照编译器的默认分配方式,由我自己分配,那怎么写呢,看下面的例子:

#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 }