Go项目怎么使用枚举

Go项目怎么使用枚举

目录

前言

为什么要有枚举

定义新类型实现枚举

protobuf中生成的枚举代码

总结

前言

哈喽,大家好,我是asong。枚举是一种很重要的数据类型,在java、C语言等主流编程语言中都支持了枚举类型,但是在Go语言中却没有枚举类型,那有什么替代方案吗? 本文我们来聊一聊这个事情;

为什么要有枚举

我们以java语言为例子,在JDK1.5之前没有枚举类型,我们通常会使用int常量来表示枚举,一般使用如下:

public static final int COLOR_RED = 1; public static final int COLOR_BLUE = 2; public static final int COLOR_GREEN = 3;

使用int类型会存在以下隐患:

不具备安全性,声明时如果没有使用final就会造成值被篡改的风险;

语义不够明确,打印int型数字并不知道其具体含义

于是乎我们就想到用常量字符来表示,代码就变成了这样:

public static final String COLOR_RED = "RED"; public static final String COLOR_BLUE = "BLUE"; public static final String COLOR_GREEN = "GREEN";

这样也同样存在问题,因为我们使用的常量字符,那么有些程序猿不按套路出牌就可以使用字符串的值进行比较,这样的代码会被不断模仿变得越来越多的,然后屎山就出现了;

所以我们迫切需要枚举类型的出现来起到约束的作用,假设使用一个枚举类型做入参,枚举类型就可以限定沙雕用户不按套路传参,这样就可以怼他了,哈哈~;

使用枚举的代码就可以变成这样,传了枚举之外的类型都不可以了;

public class EnumClass {     public static void main(String [] args){         Color color = Color.RED;         convert(color);         System.out.println(color.name());     }     public static void convert(Color c){         System.out.println(c.name());     } } enum Color{     RED,BLUE,GREEN; }

Go语言就没有枚举类型,我们该使用什么方法来替代呢?

定义新类型实现枚举

枚举通常是一组相关的常量集合,Go语言中有提供常量类型,所以我们可以使用常量来声明枚举,但也同样会遇到上述的问题,起不到约束的作用,所以为了起到约束我们可以使用Go语言另外一个知识点 -- 类型定义,Go语言中可以使用type关键字定义不同的类型,我们可以为整型、浮点型、字符型等定义新的类型,新的类型与原类型转换需要显式转换,这样在一定程度上也起到了约束的作用,我们就可以用Go语言实现如下枚举:

type OrderStatus int const (     CREATE OrderStatus = iota + 1     PAID     DELIVERING     COMPLETED     CANCELLED ) func main() {     a := 100     IsCreated(a) }

上面的代码就会报错:

./main.go:19:12: cannot use a (variable of type int) as type OrderStatus in argument to IsCreated

定义新的类型可以起到约束作用,比如我们要检查状态机,入参限定了必须是OrderStatus类型,如果是int类型就会报错。

上面我们的枚举实现方式只能获取枚举值,获取不到其映射的字面意思,所以我们可以优化一下,实现String方法,使用官方提供的cmd/string来快速实现,代码如下:

//go:generate stringer -type=OrderStatus type OrderStatus int const (     CREATE OrderStatus = iota + 1     PAID     DELIVERING     COMPLETED     CANCELLED )

执行命令go generate ./...生成orderstatus_string.go文件:

import "strconv" func _() {     // An "invalid array index" compiler error signifies that the constant values have changed.     // Re-run the stringer command to generate them again.     var x [1]struct{}     _ = x[CREATE-1]     _ = x[PAID-2]     _ = x[DELIVERING-3]     _ = x[COMPLETED-4]     _ = x[CANCELLED-5] } const _OrderStatus_name = "CREATEPAIDDELIVERINGCOMPLETEDCANCELLED" var _OrderStatus_index = [...]uint8{0, 6, 10, 20, 29, 38} func (i OrderStatus) String() string {     i -= 1     if i < 0 || i >= OrderStatus(len(_OrderStatus_index)-1) {         return "OrderStatus(" + strconv.FormatInt(int64(i+1), 10) + ")"     }     return _OrderStatus_name[_OrderStatus_index[i]:_OrderStatus_index[i+1]] } protobuf中生成的枚举代码

Go语言使用protobuf会生成对应的枚举代码,我们发现其中也是使用定义新的类型的方式来实现的,然后在封装一些方法,我们来赏析一下protobuf生成的枚举代码:

const (     CREATED  OrderStatus = 1     PAID OrderStatus = 2     CANCELED OrderStatus = 3 ) var OrderStatus_name = map[int32]string{     1: "CREATED",     2: "PAID",     3: "CANCELED", } var OrderStatus_value = map[string]int32{     "CREATED":  1,     "PAID": 2,     "CANCELED": 3, } func (x OrderStatus) Enum() *OrderStatus {     p := new(OrderStatus)     *p = x     return p } func (x OrderStatus) String() string {     return proto.EnumName(OrderStatus_name, int32(x)) } func (x *OrderStatus) UnmarshalJSON(data []byte) error {     value, err := proto.UnmarshalJSONEnum(OrderStatus_value, data, "OrderStatus")     if err != nil {         return err     }     *x = OrderStatus(value)     return nil } 总结

虽然Go语言没有提供枚举类型,但是我们也可以根据Go语言的两个特性:常量和定义新类型来实现枚举,方法总比困难多吗,开源库是优秀的,我们往往可以从高手那里里学习很多,记住,请永远保持一个学徒之心;

到此这篇关于Go项目怎么使用枚举的文章就介绍到这了,更多相关Go 枚举内容请搜索易知道(ezd.cc)以前的文章或继续浏览下面的相关文章希望大家以后多多支持易知道(ezd.cc)!

推荐阅读

    电脑硬盘csgo凭空消失|csgo突然消失

    电脑硬盘csgo凭空消失|csgo突然消失,,1. csgo突然消失可能是系统出现卡顿,刷新一下重启试试2. csgo地图突然消失方法如下:1、在电脑中启动cs

    csgo参数设置|csgo怎么保存

    csgo参数设置|csgo怎么保存,,csgo怎么保存第一步下载csgo的官方版本。然后再下载一个5e对战平台,PS:5e的账号和csgo的账号不是一个账号。第

    aigo无线硬盘连电脑|aigo优盘连接手机

    aigo无线硬盘连电脑|aigo优盘连接手机,,1. aigo优盘连接手机不管是爱国者U盘还是其他的U盘,要导入华为手机的话,首先需要有一个转接头,一头插

    csgo高手快捷键|csgo快捷键指令

    csgo高手快捷键|csgo快捷键指令,,1. csgo快捷键指令反恐精英全球攻势游戏中,死亡竞赛的回合时间60分钟:mp_roundtime 60,休闲/竞技模式的每局

    aigo电脑主机系统重启|csgo重启电脑

    aigo电脑主机系统重启|csgo重启电脑,,csgo重启电脑如果重启成功应该是不需要,相反就需重新安装csgo重启电脑重连不上直接打开游戏,通过游戏

    csgo电脑等级|csgo电脑等级指令

    csgo电脑等级|csgo电脑等级指令,,csgo电脑等级指令如图:竞技匹配等级另外还有每打一局都加经验的那个等级是满级为40,满了之后可兑换赛季纪

    csgo设置准星|csgo设置准星大小

    csgo设置准星|csgo设置准星大小,,csgo设置准星大小csgo怎么设置准星方法:1.打开CSGO游戏,打开创意工坊,查找crashz' Crosshair Generator v2

    duolingo电脑版|Duolingo软件

    duolingo电脑版|Duolingo软件,,Duolingo软件1.百词斩:2.英语流利说:“英语流利说”是一款融合创新口语教学理念和尖端语音评估技术的英语口