iota

Go语言的iota常用于const表达式中,其值是从0开始的,const声明块中每增加一行,iota值都会自增1。

使用iota可以简化常量的定义,但其规则必须牢记,否则在阅读源码时可能会造成误解或者障碍。本章我们尝试从编译器的角度来理解iota,从而加深认识。

特性速览

在常量声明语句中,iota经常用于声明连续的整型常量。iota的取值与其出现的位置强相关。

  • iota在const关键字出现时被重置为0
  • const声明块中每新增一行,iota的值自增1

这种描述本身没有错误,在简单的语句中套用这种规则可以快速的计算iota的值,但在面对复杂的语句时这种规则往往充满了歧义。实际上从编译器的角度看iota,其取值的规则只有一条:

  • iota代表了const声明块的行索引(下标从0开始)

这样子理解更贴近编译器的实现逻辑,也更准确。除此之外,const声明还有一个特点,即如果为常量指定了一个表达式,但后续的常量没有表达式,则继承上面的表达式。

接下来,根据这个规则来分析一个复杂的常量声明:

const (bit0, mask0 = 1 << iota, 1<<iota - 1 //const 声明第0行,即 iota==0bit1, mask1                          //const 声明第1行,即iota==1,表达式继承上面的语句_, _                                 // const 声明第2行,即iota==2bit3, mask3                          //const 声明第3行,即iota==3
)
  • 第0行的表达式展开即 bit0 , mask0 = 1<<0 ,1<<0-1 , 所以bit0=1,mask0=0
  • 第1行的表达式继承上一行,即 bit0 , mask0 = 1<<1 ,1<<1-1 , 所以bit0=2 , mask0=1
  • 第2行没有定义常量
  • 第3行没有指定表达式,继承第1行,即 bit0 , mask0 = 1<<3 ,1<<3-1 , 所以bit0=8 , mask0=7

实现原理

iota标识符仅能用于常量声明语句中,它的取值与常量声明块中的代码行数强相关,可以说它标识的正是常量声明语句中的行数(从0开始)。那么它为什么会表现出这样子的行为呢?

答案在于编译器处理常量声明语句的方式,

在编译器代码中,每个常量声明语句使用ValueSpec结构表示:

ValueSpec struct {Doc *CommentGroup      //associated documentation ; or nilNames []*Ident       //value names (len(Names) > 0)Type Expr                  //value type ; or nilValues []Expr          //initial values ; or nilComment *CommentGroup  //line comments ; or nil
}

ValueSpec 结构不仅可以用来表示常量声明,还可以表示变量声明,不过它仅表示一行声明语句,比如:

const (//常量的注释(文档)a , b = iota ,iota    //常量的行注释
)

上面的常量声明块中仅包括一行声明语句,该语句对应一个ValueSpec结构。

  • Doc表示块注释,往往会出现在文档的注释中
  • Name表示常量的名字,使用切片表示单行语句中声明的多个常量
  • Type 为常量类型
  • Value为常量值,与Name对应,表示常量的初始值
  • Comment表示行注释

编译器在构造常量时,实际上会编译ValueSpec结构中的Names切片来逐个生成常量。相关代码比较复杂,下面给出构造常量的伪算法,从中可以看出iota的作用。

通常const语句块中包含多行常量声明,那么就会对应多个ValueSpec结构,我们使用ValueSpecs表示多个ValueSpec结构,编译器构造常量的过程如下:

for iota,spec := range ValueSpecs {for i,name := range spec.Names {obj := NewConst(name,iota...)...}
}

由上面的代码可以看出iota的本质,它仅代表常量声明的索引,所以它会表现出以下特征:

  • 单个const声明块中从0开始取值
  • 单个const声明块中,每增加一行声明,iota的取值增1,即便声明中没有使用iota也是如此
  • 单行声明语句中,即便出现多个iota,iota的取值也会保持不变

golang数据结构初探之iota相关推荐

  1. golang数据结构初探之管道chan

    golang数据结构初探之管道chan 管道是go在语言层面提供的协程之间的通信方式,比unix的管道更易用也更轻便. 特效速览 初始化 声明和初始化管道的方式主要有以下两种: 变量声明 使用内置函数 ...

  2. golang数据结构初探之字典map

    Map Go语言的map底层使用Hash表实现的 特性预览 操作方式 初始化 map分别支持字面量初始化和内置函数make()初始化 字面量初始化 func MapInit() {m := map[s ...

  3. golang数据结构初探之动态数组slice

    动态数组slice slice 又称动态数组,依托于数组实现,可以方便的进行扩容和传递,实际使用时比数组更灵活.但正是因为灵活,实际使用时更容易出错,避免出错的最好方法便是了解其实现原理. 特性速览 ...

  4. golang数据结构初探之字符串string

    字符串string string 是Go语言中的基础数据类型. 特性速览 声明 声明string变量非常简单,常见的方式有以下两种: 声明一个空字符串后再赋值 var s string s = &qu ...

  5. 鸡尾酒排序算法c语言,[golang] 数据结构-鸡尾酒排序

    吐个槽 又是一个不正经取名的排序算法.真要说和鸡尾酒间的关系,大概就是想喝到鸡尾酒(得到排序好的队列)就要摇晃酒杯让不同的成分混合均匀(向两个方向冒泡排序) 原理 鸡尾酒排序(Cocktail Sor ...

  6. golang数据结构_Go数据结构的完整指南

    golang数据结构 This week, in various articles on this blog, I posted an analysis and implementation of t ...

  7. Golang modules 初探

    2019独角兽企业重金招聘Python工程师标准>>> 今天天色刚刚亮起,起床看到golang 1.11正式发版了,有着两个重要的特性:modules和WebAssembly. 本博 ...

  8. Duang~ Golang 学习初探

    Duang~  Golang学习初步体验,一直以来都对Go语言有一定的喜感,今天花了点时间初步的了解了下Go,其实很多东西弄个小例子go run下会明白很多东西的. 本人开发工具使用的是GoSubli ...

  9. Redis原理以及底层数据结构初探

    什么是Redis? 非关系型的键值对数据库,可以根据键以O(1)的时间复杂度取出或插入关联值 Redis的数据是存在内存中的 键值对中键的类型可以是字符串,整型,浮点型等,且键是唯一的 键值对中的值类 ...

最新文章

  1. live的domain服务
  2. VS代码提示不出现或者提示变成英文或者各种奇葩问题的解决
  3. 复制公钥到多个服务器脚本
  4. 1.26 Java使用自定义包
  5. C++ namespace 命名空间
  6. 就是肝!计算机基础知识总结与操作系统 PDF 下载
  7. android 界面切换教程
  8. 关于Oracle undostat中的2012和ORA-01555问题的自我解答
  9. 多目标分类的混淆矩阵_用于目标检测的混淆矩阵
  10. Codeforces 963B Destruction of a Tree 【贪心】
  11. UVA103 dp基础题,DAG模型
  12. ios开发常用RGB色值
  13. webpack4打包js
  14. 安全之路 —— C/C++开3389端口(远程终端)
  15. 在正式使用计算机账务系统的银行对账功能,会计电算化账务处理系统中,银行对账的功能有哪些? 爱问知识人...
  16. ntp校时器(网络对时服务器)自动化系统技术应用方案
  17. HTML+CSS网页设计期末课程大作——XXXXX (X页) HTML5网页设计成品_学生DW静态网页设计_web课程设计网页制作
  18. OpenCV——图像处理入门:膨胀与腐蚀、图像模糊、边缘检测
  19. QQ浏览器及360浏览器兼容模式下怎么处理sessionStorage数据
  20. 自动驾驶在挑战中进化的感知能力

热门文章

  1. spring-webflux中FluxDataBuffer 转String
  2. 原神3.2服务端架设服务器搭建教程ubuntu系统(保姆级)
  3. Java在Quant应用_BigQuant人工智能量化平台使用
  4. Highlight Detection with Pairwise Deep Ranking for First-Person Video Summarization(论文翻译)
  5. 解决win10系统驱动正常却无声音问题
  6. Docker实践:python应用容器化
  7. 蚂蚁算法C语言解决,蚂蚁优化算法在解决CVRP中的应用
  8. php高级部署,php部署【设置流程】
  9. iosepub阅读器_超赞EPUB阅读器 - Neat Reader
  10. 5.1测试用例和设计方法