golang

golang存在枚举吗

c++go

通常会写成如下形式。

//ColumnType 列类型
type ColumnType int

const (
	CtNone         ColumnType                            = iota //无效
	CtInt                                                       //整数
	CtString                                                    //文本
	CtFloat                                                     //小数
	CtEnum                                                      //枚举
	CtBitEnum                                                   //位枚举
	CtVecDataPKey                                               //主枚举列
	CtVecDataCKey                                               //子枚举列
	CtVecDataValue                                              //数据列
	CtRealEnd                                                   //真实类型结束
	CtLogicBegin   = 100                                        //逻辑类型 为了避免增减枚举导致的版本不对应绕过此处,因此特殊处理一下
	CtData         = iota + CtLogicBegin - CtRealEnd - 1        // 压缩过后的逻辑数据
	CtAttrs                                                     // 属性集
)

一般如下使用

for i, col := range logic.Columns {
		// 非复杂类型
		switch col.ExcelType {
		case CtVecDataPKey, CtVecDataCKey:
			continue
		case CtVecDataValue:
			if i == len(logic.Columns)-1 ||
				(logic.Columns[i+1].ExcelType != CtVecDataPKey &&
					logic.Columns[i+1].ExcelType != CtVecDataCKey) {
				excel.ColumnTypes = append(excel.ColumnTypes, CtData)
			}
		case CtBitEnum:
			excel.ColumnTypes = append(excel.ColumnTypes, CtAttrs)
		default:
			excel.ColumnTypes = append(excel.ColumnTypes, col.ExcelType)
		}
	}
CtEnumType(1111)caseif

如何使用枚举

容错

int
CtNone         ColumnType                            = iota //无效

需要指定有效区域,对区域外的枚举过滤掉。

CtInt                                                       //整数
CtString                                                    //文本
CtFloat                                                     //小数
CtEnum                                                      //枚举
CtBitEnum                                                   //位枚举
CtVecDataPKey                                               //主枚举列
CtVecDataCKey                                               //子枚举列
CtVecDataValue                                              //数据列
CtRealEnd                                                   //真实类型结束
if cType == CtNone || cType >= CtRealEnd {
	return
}

使用iota

const

最常见的使用方法是

const (
  a = iota
	b
	c
	d
)

此时,abcd的值依次为0、1、2、3。

iota
a = iota * 2
b
c
d

此时abcd的值依次为0、2、4、6

通过这个方式我们可以实现位枚举

a = 1 << iota
b
c
d

值依次为 1、2、4、8。

itoa
a = iota
b
c
d
e = 1 << iota

值依次为 0、1、2、3、16

有些人可能会想,我们能不能和c的枚举一样跳过某些值或者指定某一个枚举后,枚举又从另外一个值开始呢。于是写出了以下c风格代码。

a = iota
b
c
d = 100 // 以下是另外一组
e
f
goland
a = ioat
b
c
d = 100 + ioat // 以下是另外一组
e
f
itoagolandgoland

正确的写法应该是

a = ioat
b
c
normalEnd
otherBegin = 100 + ioat - normalEnd // 以下是另外一组
d
e

此时的逻辑是正确的

abcde的值依次为0、1、2、101、102,就是有那么一点扭曲。

go_
a = ioat
_
_
b

此时ab的值依次为0、3。

代码规范

我个人建议为了避免造成误解,枚举变量以e开头。枚举值以枚举类型的缩写开头例如。

var eType ColumnType = CtInt  
pigo