《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实现原理并高效使用

《Go语言精进之路》读书笔记 | 使用defer让函数更简洁更健壮

《Go语言精进之路》读书笔记 | 汇总

《Go语言精进之路》读书笔记 | 使用一致的变量声明形式

《Go语言精进之路》读书笔记 | 使用无类型常量简化代码