《Go语言精进之路》读书笔记 | 使用iota实现枚举常量
Posted COCOgsta
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《Go语言精进之路》读书笔记 | 使用iota实现枚举常量相关的知识,希望对你有一定的参考价值。
书籍来源:《Go语言精进之路:从新手到高手的编程思想、方法和技巧》
一边学习一边整理读书笔记,并与大家分享,侵权即删,谢谢支持!
附上汇总贴:《Go语言精进之路》读书笔记 | 汇总_COCOgsta的博客-CSDN博客
与其他C家族主流语言(如C++、Java)不同,Go语言没有提供定义枚举常量的语法。通常使用常量语法定义枚举常量:
const (
Sunday = 0
Monday = 1
Tuesday = 2
Wednesday = 3
Thursday = 4
Friday = 5
Saturday = 6
)
复制代码
Go的const语法提供了“隐式重复前一个非空表达式”的机制:
const (
Apple, Banana = 11, 22
Strawberry, Grape
Pear, Watermelon
)
复制代码
常量定义的后两行没有显式给予初始赋值,Go编译器将为其隐式使用第一行的表达式,上述定义等价于:
const (
Apple, Banana = 11, 22
Strawberry, Grape = 11, 22
Pear, Watermelon = 11, 22
)
复制代码
Go在这个机制的基础上又提供了神器iota,可以定义满足各种场景的枚举常量了。
iota是Go语言的一个预定义标识符,它表示的是const声明块(包括单行声明)中每个常量所处位置在块中的偏移值(从零开始)。
下面是Go标准库中sync/mutex.go中的一段枚举常量的定义:
// $GOROOT/src/sync/mutex.go (go 1.12.7)
const (
mutexLocked = 1 << iota
mutexWoken
mutexStarving
mutexWaiterShift = iota
starvationThresholdNs = 1e6
)
复制代码
这是一个很典型的诠释iota含义的例子,我们逐行来看。
mutexLocked = 1 << iota:此时iota的值为0,我们得到mutexLocked这个常量的值为1 << 0,即1。
mutexWoken:根据“隐式重复前一个非空表达式”机制,该行等价于mutexWoken = 1 << iota。由于该行是const块中的第二行,因此偏移量iota的值为1,我们得到mutexWoken这个常量的值为1<< 1,即2。
mutexStarving:该行等价于mutexStarving = 1 << iota,由于在该行的iota的值为2,因此我们得到mutexStarving这个常量的值为 1 << 2,即4。
mutexWaiterShift = iota:由于该行为第四行,iota的偏移值为3,因此mutexWaiterShift的值就为3。
位于同一行的iota即便出现多次,其值也是一样的:
const (
Apple, Banana = iota, iota + 10 // 0, 10 (iota = 0)
Strawberry, Grape // 1, 11 (iota = 1)
Pear, Watermelon // 2, 12 (iota = 2)
)
复制代码
如果要略过iota = 0,从1开始正式定义枚举常量:
// $GOROOT/src/syscall/net_js.go,go 1.12.7
const (
_ = iota
IPV6_V6ONLY // 1
SOMAXCONN // 2
SO_ERROR // 3
)
复制代码
也可以使用类似方式略过某一枚举值:
const (
_ = iota // 0
Pin1
Pin2
Pin3
_ // 相当于_ = iota,略过了4这个枚举值
Pin5 // 5
)
复制代码
iota的加入让Go在枚举常量定义上的表达力大增,主要体现在如下几方面。
(1)iota可以参与常量初始化表达式的计算,为枚举常量赋初值
(2)Go的枚举常量不限于整型值,也可以定义浮点型的枚举常量
(3)iota使得维护枚举常量列表更容易
(4)使用有类型枚举常量保证类型安全
以上是关于《Go语言精进之路》读书笔记 | 使用iota实现枚举常量的主要内容,如果未能解决你的问题,请参考以下文章
《Go语言精进之路》读书笔记 | 了解切片实现原理并高效使用
《Go语言精进之路》读书笔记 | 了解string实现原理并高效使用