最近在学习GO语言,而后发现有一个特殊常量是之前没有接触过的,比较感兴趣,这里给你们介绍一下。学习
iota,特殊常量,能够被认为是一个能够被编译器修改的常量。spa
核心概念:iota在const关键字出现时将被重置为0(const内部的第一行以前),const中每新增一行常量声明将使iota计数一次。code
这么来看,简单的来讲,iota能够被认为是单个const声明块内的行索引。blog
咱们先来看一个例子,你就能简单的理解iota的基本做用:索引
// heihei package main import ( "fmt" ) func main() { const a=iota //第一个const声明块,仅声明了一个a.iota在此次赋值时值为0,赋值完成后,a声明语句执行完毕,iota等于1. const ( b=iota c=iota ) //第二个const声明块,声明了两个值b和c.可是在这里的一开始,iota依然等于0,由于这是一个新的const声明块的开始.随后,iota在给b赋值完毕后,b声明语句执行完毕,iota变成1,而后对c同理. fmt.Printf("%d", a) //由上可知,此处输出为0 fmt.Println() fmt.Printf("%d,%d",b,c) //由上可知,此处输出为0,1 fmt.Println() }
如上的代码,运行结果以下:字符串
可见,与注释处的说明是一致的。编译器
下面再介绍一个简写的形式,先来看代码:io
// heihei package main import ( "fmt" ) func main() { const ( a = iota b c ) fmt.Printf("%d,%d,%d", a, b, c) fmt.Println() }
在这个例子中,const声明块里采起了简写的形式,即:若当前行没有赋值语句被书写,则赋值自动采用向上、最近的一个有赋值语句的右侧值。因为b、c均没有赋值,因此,会自动采用最近的一个赋值的值,也就是iota。编译
那么,想必在这样的操做下,你们应该明白会输出什么了。对了,就是0,1,2.class
那么,若是赋值的不是单变量/常量,而是一个表达式,结果会发生变化吗?咱们来看代码:
// heihei package main import ( "fmt" ) func main() { const ( i = 3 << iota j k ) fmt.Printf("%d,%d,%d", i, j, k) fmt.Println() }
先来看结果:
能够看到,这样,依然知足前述“省略赋值”状况下的规则,依然是复制了向上、最近的右侧表达式。
好,在了解了上述的一些规则和基础以后,咱们来看一个稍微复杂一点的例子,直接上代码:
// heihei package main import ( "fmt" ) func main() { const ( a = 666 b = iota c d = "hehehe" e f = 2 << iota ) fmt.Printf("%d,%d,%d,%s,%s,%d", a, b, c, d, e, f) fmt.Println() }
(请自敲代码复刻的注意,由以前规则,能够预见d和e一定为字符串,因此格式输出时换成了%s。固然,也欢迎你继续保持%d,看看结果如何~)
咱们先来看结果:
能够看到,在依然遵循了“未当场赋值的声明遵循向上、最近的赋值表达式”这一规则下,即便中间的赋值再也不和iota有关,iota依然保持了计数。并在中间的结果中得以体现。
换言之——即便你的表达式中从未出现iota,“幽灵般”的iota依然会默默进行计数,其计数规则与最开始所阐述保持一致。
如今,你应该能更加深入的理解“简单的来讲,iota能够被认为是单个const声明块内的行索引。”这一句话了。