Go语言枚举——无中生有

    Go语言中没有枚举这种数据类型的,但是可以使用const配合iota模式来实现,如果要为枚举添加方法的话还涉及到类型的定义,以及为新建类型添加方法。所以在开始介绍实现go语言的枚举实现之前,我们先来看看类型别名(在Go1.9版本新增的功能,主要用于代码升级、迁移中类型的兼容性问题)和类型定义的区别。

 

写法对比:

类型别名的写法:

type TypeAlias = Type // TypeAlias只是Type的别名,本质上TypeAlias和Type是同一个类型。

类型定义的写法:

type TypeNew = Type // TypeNew 是一个新的类型,拥有Type相关的所有属性和方法

 

通过以下示例来验证以上观点:

package main // 定义包名



import "fmt"



// MyInt 将MyInt 定义为int类型

type MyInt int



// IntAlias 将int 取名为IntAlias

type IntAlias = int



// 为MyInt定义一个add方法

func (a MyInt) add(b int) {



}



// 为IntAlias 定义remove方法,编译报错:cannot define new methods on non-local type int

// func (a IntAlias) remove(b int) {



// }



// 编译器提示不能在非本地类型int上定义新方法,因为type IntAlias = int只是取了一个别名,实际类型还是int类型,而int类型不再main包里,称之为非本地类型。相反的type MyInt int定义了一个新的类型MyInt,而这个类型是属于main包内的,所以支持定义方法



func main() {

  // 声明MyInt 变量a

  var a MyInt

  // 查看变量a的类型

  fmt.Printf("a type = %T\n", a)



  // 声明IntAlias 变量b

  var b IntAlias

  // 查看变量b的类型

  fmt.Printf("b type = %T\n", b)



  /*

    输出结果:

      a type = main.MyInt

      b type = int

  */

}


从上例输出结果可以得知:变量a的类型为main.MyInt,表示main包下定义的MyInt类型,而变量b的类型依然是int类型,说明IntAlias类型只会在代码中存在,编译完成时不会有IntAlias类型

另外,上例中也给大家演示了为MyInt和IntAlias类型添加方法,代码中,可以顺利的为MyInt添加方法。但是如果为IntAlias添加方法的话会报编译错误,编译器提示不能在非本地类型int上定义新方法。因为type IntAlias = int只是取了一个别名,实际类型还是int类型,而int类型不在main包里,称之为非本地类型。相反的type MyInt int定义了一个新的类型MyInt,而这个类型是定义在main包内,所以支持为其定义方法。

 

上面简单的和大家分享了类型别名和类型定义的区别,也和大家演示了如何为定义的类型添加方法。下面让我们学以致用,通过以上特性来实现Go语言的枚举

package main // 定义包名



import "fmt"



// ColorType 定义一个ColorType 类型

type ColorType int



const (

  // Black 使用iota进行常量值自动生成

  Black ColorType = iota

  // Yellow 黄色

  Yellow

  // Red 红色

  Red

  // Blue 蓝色

  Blue

)



// c#的枚举有toString的功能,可以为ColorType定义toString方法实现类似的功能

func (t ColorType) toString() string {

  switch t {

  case Black:

    return "Black"

  }



  return ""

}



func main() {



  fmt.Println(Black, Yellow, Red, Blue)



  fmt.Println(Black.toString())

}

以上示例简单的和大家演示了Go语言枚举的实现,但是toString()采用switch的方式个人感觉有点low,是否可以考虑采用Go语言的反射来简化代码呢?这个有待后续验证,目前还没去研究Go语言的反射机制。

 

你可能感兴趣的:(GoLearn)