Go iota——常量计数器的使用方法

在看 Go 源码时,既然遇到 iota 看得我一脸懵逼,所以打算全面地好好理解 Go 的 itoa

看的源码是 C:\Go\src\sync\mutex.go,itoa 相关部分的源码是:

1
2
3
4
5
6
7
8
9
10
const (
mutexLocked = 1 << iota // mutex is locked
mutexWoken
mutexStarving
mutexWaiterShift = iota
// Mutex fairness.
//
// Mutex can be ...
starvationThresholdNs = 1e6
)

将其打印出来的值是:

1
2
3
4
5
mutexLocked:1
mutexWoken:2
mutexStarving:4
mutexWaiterShift:3
starvationThresholdNs:1e+06

一脸懵逼,那么就从基础开始,从头来过吧~

首先 itoa 是什么?

itoa 官方定义与示例

iota 是 Go语言 的常量计数器,只能在常量的表达式中使用,即只能和 const 搭配使用,
其特性如下:

1、每次 const 出现时,都会让 iota 初始化为 0.

1
2
3
4
5
6
const a = iota // a=0 

const ( // const 再次出现
b = iota // b=0 // itoa 被初始化为 0
c // c=1
)

2、自定义类型

自增长常量经常包含一个自定义枚举类型,允许你依靠编译器完成自增设置。

1
2
3
4
5
6
7
8
type NewType int

const (
T1 NewType = iota // 0
T2 // 1
T3 // 2
T4 // 3
)

3、可跳过的值

1
2
3
4
5
6
7
8
9
10
type AudioOutput int

const (
OutMute AudioOutput = iota // 0 -- 静音
OutMono // 1 -- 单声道
OutStereo // 2 -- 立体声
_ // 跳过一个值 3
_ // 跳过一个值 4
OutSurround // 5 -- 环绕立体声
)

左移运算符 <<, 用来将一个数的各二进制位全部左移若干位,
移动的位数由右操作数指定,右操作数必须是非负值,其右边空出的位用0填补,高位左移溢出则舍弃该高位。

4、位掩码表达式

1
2
3
4
5
6
7
8
9
type Allergen int

const (
IgEggs Allergen = 1 << iota // 1 << 0 将 1 左移 (iota=0) 位得 00000001 = 1
IgChocolate // 1 << 1 将 1 左移 (iota=1) 位得 00000010 = 2
IgNuts // 1 << 2 将 1 左移 (iota=2) 位得 00000100 = 4
IgStrawberries // 1 << 3 将 1 左移 (iota=3) 位得 00001000 = 8
IgShellfish // 1 << 4 将 1 左移 (iota=4) 位得 00010000 = 16
)

5、定义数量级

1
2
3
4
5
6
7
8
9
10
11
12
13
type ByteSize float64

const (
_ = iota // 过分配给空白标识符忽略第一个值
KB ByteSize = 1 << (10 * iota) // 1 << (10*1) 将 1 左移 10 位得 ‭010000000000‬ = 1024
MB // 1 << (10*2) 将 1 左移 20 位
GB // 1 << (10*3) 将 1 左移 30 位
TB // 1 << (10*4) 将 1 左移 40 位
PB // 1 << (10*5) 将 1 左移 50 位
EB // 1 << (10*6) 将 1 左移 60 位
ZB // 1 << (10*7) 将 1 左移 70 位
YB // 1 << (10*8) 将 1 左移 80 位
)

6、定义在一行的情况

1
2
3
4
5
const (
Apple, Banana = iota + 1, iota + 2 // Apple = 1; Banana = 2
Cherimoya, Durian // Cherimoya = (Apple + 1)=2; Durian = (Banana + 1)=3
Elderberry, Fig // Elderberry = (Cherimoya + 1)=3; Fig = (Durian + 1)=4
)

7、中间插队

1
2
3
4
5
6
7
8
const (
a = iota // 0
b = 5 // 5
c = iota // 2
d = 6 // 6
e // 6
f // 6
)
1
2
3
4
5
6
7
8
9
10
const (
mutexLocked = 1 << iota // 1 << 0 将 1 左移 (iota=0)位,得 00000001 = 1
mutexWoken // 1 << 1 将 1 左移 (iota=1)位,得 00000010 = 2
mutexStarving // 1 << 1 将 1 左移 (iota=2)位,得 00000100 = 4
mutexWaiterShift = iota // 将 (iota=3) 赋值给 mutexWaiterShift = 3
// Mutex fairness.
//
// Mutex can be ...
starvationThresholdNs = 1e6
)

总结:

可以看出 itoa 虽然很方便,但代码不好读,还是老老实实写人类看得懂的代码吧~

觉得文章对您有帮助,请我喝瓶肥宅快乐水可好 (๑•̀ㅂ•́)و✧
  • 本文作者: 阿彬~
  • 本文链接: https://iweixubin.github.io/posts/go/itoa/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 免责声明:本媒体部分图片,版权归原作者所有。因条件限制,无法找到来源和作者未进行标注。
         如果侵犯到您的权益,请与我联系删除