Golang中iota逻辑不一致问题解析
Golang中iota逻辑不一致问题解析
const (
zero myConst = iota
one
three = iota + 1
foure
five = iota + 1
)
func testIota() {
// 3 4 5 为什么不是 3 4 6
fmt.Println(three, foure, five)
}
为什么输出是 “3 4 5” 而不是 “3 4 6”?执行环境为 go version go1.13.10 linux/amd64。
3 回复
iota 是常量声明中的“索引”。它从 0 开始单调递增至正无穷。
在使用了 iota 的 const 代码块中进行赋值,并不会改变 iota 本身,而只是改变了计算常量值的公式。因此,对于 five 这个常量,你实际上是在告诉 Go 使用与之前相同的方式来计算其值,即在 iota(此时为 4)的基础上加 1。
const (
zero = iota // 0
one // 1
two // 2
three // 3
five = iota // 4
)
在Go语言中,iota的行为是严格遵循规则的,这里并没有逻辑不一致。让我们分析一下你的代码:
const (
zero myConst = iota // iota = 0, zero = 0
one // iota = 1, one = 1
three = iota + 1 // iota = 2, three = 2 + 1 = 3
foure // 没有显式赋值,继承上一个表达式 iota + 1,此时 iota = 3, foure = 3 + 1 = 4
five = iota + 1 // iota = 4, five = 4 + 1 = 5
)
关键点在于:
iota在每个const声明块中从0开始,每增加一行声明就递增1- 当一行没有显式赋值时,它会复制上一行的表达式
所以执行过程是:
zero: iota=0, zero=0one: iota=1, one=1 (复制上一行的iota表达式)three: iota=2, three=2+1=3foure: iota=3, foure=3+1=4 (复制上一行的iota+1表达式)five: iota=4, five=4+1=5
如果你想得到"3 4 6"的输出,需要这样写:
const (
zero myConst = iota
one
three = iota + 1 // 3
foure // 4
_ // 跳过5
five = iota + 1 // 6
)
func testIota() {
fmt.Println(three, foure, five) // 输出: 3 4 6
}
或者更清晰地:
const (
zero myConst = iota
one
three = iota + 1 // iota=2, 2+1=3
foure = iota + 1 // iota=3, 3+1=4
five = iota + 2 // iota=4, 4+2=6
)
iota的行为在Go语言中是明确且一致的:它是一个在当前const声明块中每行递增的计数器,当一行没有显式赋值时会复制上一行的表达式。

