iota是golang语言的常量计数器,只能在常量的表达式中使用。

iota在const关键字出现时将被重置为0(const内部的第一行之前),const中每新增一行常量声明将使iota计数一次(iota可理解为const语句块中的行索引)。

使用iota能简化定义,在定义枚举时很有用。

举例如下:

1、iota只能在常量的表达式中使用。

fmt.Println(iota)
编译错误: undefined: iota

2、每次 const 出现时,都会让 iota 初始化为0.【自增长】

const a = iota // a=0
const (
  b = iota          //b=0
  c                      //c=1
)

3、自定义类型

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

type Stereotype int

const (
    TypicalNoob Stereotype = iota // 0
    TypicalHipster                               // 1
    TypicalUnixWizard                         // 2
    TypicalStartupFounder                // 3
)

下面是来自time包的例子,它首先定义了一个Weekday命名类型,然后为一周的每天定义了一个常量,从周日0开始。在其它编程语言中,这种类型一般被称为枚举类型。

type Weekday int

const (
Sunday Weekday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)

周一将对应0,周一为1,如此等等。

4、可跳过的值

设想你在处理消费者的音频输出。音频可能无论什么都没有任何输出,或者它可能是单声道,立体声,或是环绕立体声的。
这可能有些潜在的逻辑定义没有任何输出为 0,单声道为 1,立体声为 2,值是由通道的数量提供。
所以你给 Dolby 5.1 环绕立体声什么值。
一方面,它有6个通道输出,但是另一方面,仅仅 5 个通道是全带宽通道(因此 5.1 称号 - 其中 .1 表示的是低频效果通道)。
不管怎样,我们不想简单的增加到 3。
我们可以使用下划线跳过不想要的值。

type AudioOutput int

const (
    OutMute AudioOutput = iota // 0
    OutMono                       // 1
    OutStereo                     // 2
    _
    _
    OutSurround                // 5
)

5、位掩码表达式

iota 可以做更多事情,而不仅仅是 increment。更精确地说,iota 总是用于 increment,但是它可以用于表达式,在常量中的存储结果值。

type Allergen int

const (
    IgEggs Allergen = 1 << iota // 1 << 0 which is 00000001
    IgChocolate                             // 1 << 1 which is 00000010
    IgNuts                                       // 1 << 2 which is 00000100
    IgStrawberries                        // 1 << 3 which is 00001000
    IgShellfish                                // 1 << 4 which is 00010000
)

这个工作是因为当你在一个 const 组中仅仅有一个标示符在一行的时候,它将使用增长的 iota 取得前面的表达式并且再运用它,。在 Go 语言的 spec 中, 这就是所谓的隐性重复最后一个非空的表达式列表。

如果你对鸡蛋,巧克力和海鲜过敏,把这些 bits 翻转到 “on” 的位置(从左到右映射 bits)。然后你将得到一个 bit 值 00010011,它对应十进制的 19。

fmt.Println(IgEggs | IgChocolate | IgShellfish)

// output:
// 19

我们也可以在复杂的常量表达式中使用iota,下面是来自net包的例子,用于给一个无符号整数的最低5bit的每个bit指定一个名字:

type Flags uint

const (
FlagUp Flags = 1 << iota // is up
FlagBroadcast // supports broadcast access capability
FlagLoopback // is a loopback interface
FlagPointToPoint // belongs to a point-to-point link
FlagMulticast // supports multicast access capability
)

随着iota的递增,每个常量对应表达式1 << iota,是连续的2的幂,分别对应一个bit位置。使用这些常量可以用于测试、设置或清除对应的bit位的值:

测试结果:

随着iota的递增,每个常量对应表达式1 << iota,是连续的2的幂,分别对应一个bit位置。使用这些常量可以用于测试、设置或清除对应的bit位的值:

package main

import (
"fmt"
) type Flags uint const (
FlagUp Flags = 1 << iota // is up
FlagBroadcast // supports broadcast access capability
FlagLoopback // is a loopback interface
FlagPointToPoint // belongs to a point-to-point link
FlagMulticast // supports multicast access capability
) func IsUp(v Flags) bool { return v&FlagUp == FlagUp }
func TurnDown(v *Flags) { *v &^= FlagUp }
func SetBroadcast(v *Flags) { *v |= FlagBroadcast }
func IsCast(v Flags) bool { return v&(FlagBroadcast|FlagMulticast) != 0 } func main() {
var v Flags = FlagMulticast | FlagUp
fmt.Printf("%b %t\n", v, IsUp(v)) // "10001 true"
TurnDown(&v)
fmt.Printf("%b %t\n", v, IsUp(v)) // "10000 false"
SetBroadcast(&v)
fmt.Printf("%b %t\n", v, IsUp(v)) // "10010 false"
fmt.Printf("%b %t\n", v, IsCast(v)) // "10010 true"
}

运行结果:

10001 true

10000 false

10010 false

10010 true

6、定义数量级

type ByteSize float64

const (
_ = iota // ignore first value by assigning to blank identifier
KB ByteSize = 1 << (10 * iota) // 1 << (10*1)
MB // 1 << (10*2)
GB // 1 << (10*3)
TB // 1 << (10*4)
PB // 1 << (10*5)
EB // 1 << (10*6)
ZB // 1 << (10*7)
YB // 1 << (10*8)
)

下面是一个更复杂的例子,每个常量都是1024的幂:

const (
_ = 1 << (10 * iota)
KiB // 1024
MiB // 1048576
GiB // 1073741824
TiB // 1099511627776 (exceeds 1 << 32)
PiB // 1125899906842624
EiB // 1152921504606846976
ZiB // 1180591620717411303424 (exceeds 1 << 64)
YiB // 1208925819614629174706176
)

不过iota常量生成规则也有其局限性。例如,它并不能用于产生1000的幂(KB、MB等),因为Go语言并没有计算幂的运算符。

7、定义在一行的情况

const (
Apple, Banana = iota + 1, iota + 2
Cherimoya, Durian
Elderberry, Fig
)

iota 在下一行增长,而不是立即取得它的引用。

// Apple: 1
// Banana: 2
// Cherimoya: 2
// Durian: 3
// Elderberry: 3
// Fig: 4

8、中间插队

const (
    i = iota
    j = 3.14
    k = iota
    l
)

那么打印出来的结果是 i=0,j=3.14,k=2,l=3

golang 使用 iota的更多相关文章

  1. Golang的iota的特性

    Golang的iota的特性: 1. iota在每个ConstBlock中自动归0. 2. iota在每个ConstSpec后自动增1. 换言之: iota是ConstBlock中ConstSpec的 ...

  2. golang之 iota 常量生成器

    常量声明可以使用iota常量生成器初始化,它用于生成一组以相似规则初始化的常量,但是不用每行都写一遍初始化表达式.在一个const声明语句中,在第一个声明的常量所在的行,iota将会被置为0,然后在每 ...

  3. golang枚举类型 - iota用法拾遗

    在c#.java等高级语言中,经常会用到枚举类型来表示状态等.在golang中并没有枚举类型,如何实现枚举呢?首先从枚举的概念入手. 1.枚举类型定义 从百度百科查询解释如下:http://baike ...

  4. Go 语言基础(一)

    1.GO语言的第一个程序: package main import "fmt" func main() { fmt.Println("hello,world!" ...

  5. Go语言语法说明

    Go语言语法说明 go语言中的go func(){}() 表示以并发的方式调用匿名函数func 深入讲解Go语言中函数new与make的使用和区别 前言 本文主要给大家介绍了Go语言中函数new与ma ...

  6. 第一个go程序和基本语法

    目录 第一个go程序和基本语法 一. 第一个go程序 二. 基础语法 1. 命名 2. 变量 3 常量与枚举 4. 数据类型 5. fmt包的使用 6. 类型别名 7. 类型转换 8. 运算符 第一个 ...

  7. iota: Golang 中优雅的常量

    阅读约 11 分钟 注:该文作者是 Katrina Owen,原文地址是 iota: Elegant Constants in Golang 有些概念有名字,并且有时候我们关注这些名字,甚至(特别)是 ...

  8. 1、Golang基础--Go简介、环境搭建、变量、常量与iota、函数与函数高级

    1 Go语言介绍 1 golang-->Go--->谷歌公司 2009年 golang:指go语言,指的go的sdk goland:软件,ide:集成开发环境 Java写的 2 Go是静态 ...

  9. golang iota

    package main import ( "fmt" ) const ( Low = * (iota + ) Medium High ) func main() { //iota ...

随机推荐

  1. Java初始化过程

    这篇文章主要讲解Java在创建对象的时候,初始化的顺序.主要从以下几个例子中讲解: 继承关系中初始化顺序 初始化块与构造器的顺序 已经加载过的类的初始化顺序 加载父类,会不会加载子类 创建子类对象会不 ...

  2. 立即执行函数表达式(IIFE)

    原文地址:benalman.com/news/2010/11/immediately-invoked-function-expression/ 译者:nzbin 也许你还没有注意到,我是一个对术语比较 ...

  3. <译>通过PowerShell工具跨多台服务器执行SQL脚本

    有时候,当我们并没有合适的第三方工具(大部分需要付费)去管理多台数据库服务器,那么如何做最省力.省心呢?!Powershell一个强大的工具,可以很方便帮到我们处理日常的数据库维护工作 .简单的几步搞 ...

  4. .NET CoreCLR开发人员指南(上)

    1.为什么每一个CLR开发人员都需要读这篇文章 和所有的其他的大型代码库相比,CLR代码库有很多而且比较成熟的代码调试工具去检测BUG.对于程序员来说,理解这些规则和习惯写法非常的重要. 这篇文章让所 ...

  5. 【知识必备】一文让你搞懂design设计的CoordinatorLayout和AppbarLayout联动,让Design设计更简单~

    一.写在前面 其实博主在之前已经对design包的各个控件都做了博文说明,无奈个人觉得理解不够深入,所以有了这篇更加深入的介绍,希望各位看官拍砖~ 二.从是什么开始 1.首先我们得知道Coordina ...

  6. WebSocket - ( 一.概述 )

    说到 WebSocket,不得不提 HTML5,作为近年来Web技术领域最大的改进与变化,包含CSS3.离线与存储.多媒体.连接性( Connectivity )等一系列领域,而即将介绍的 WebSo ...

  7. Android SDK 在线更新镜像服务器资源

    本文转自:http://blog.kuoruan.com/24.html.感谢原作者. 什么是Android SDK SDK:(software development kit)软件开发工具包.被软件 ...

  8. BPM协同平台解决方案分享

    一.需求分析 企业信息化的过程都是从单纯解决一个业务功能问题,到解决企业内部业务流程问题,再扩展到解决不同业务流程的关联互动问题, 核心是业务的集成和业务的协同,需要有一个统一的业务协同平台. 国内的 ...

  9. 项目持续集成环境(jenkins + SVN + maven + tomcat)

    整体流程 每次SVN上代码有变动,触发自动构建动作,并部署到服务器的tomcat上,具体流程: 1.SVN上提交代码修改 2.maven执行Goals 3.将web工程打成war包 4.关闭服务器的t ...

  10. 虚拟机VMware12.05下安装Ubuntu16.04几个关键地方

    在踩了自己按照网上的教程安装Ubuntu之后,仍然踩了不少坑,鼓捣了一段时间,才达到自己想要的界面.   下面就来说说,大家可能也会遇到的情况:   1.安装ISO镜像时候,路径直接选择 你从Ubun ...