【GO基础】神奇的iota特殊常量

最近在学习GO语言,然后发现有一个特殊常量是以前没有接触过的,比较感兴趣,这里给大家介绍一下。

iota,特殊常量,可以被认为是一个可以被编译器修改的常量。

核心概念:iota在const关键字出现时将被重置为0(const内部的第一行之前),const中每新增一行常量声明将使iota计数一次。

这么来看,简单的来说,iota可以被认为是单个const声明块内的行索引

我们先来看一个例子,你就能简单的理解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()

}

如上的代码,运行结果如下:

可见,与注释处的说明是一致的。

下面再介绍一个简写的形式,先来看代码:

// 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.

那么,如果赋值的不是单变量/常量,而是一个表达式,结果会发生变化吗?我们来看代码:

// 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声明块内的行索引。”这一句话了。

原文地址:https://www.cnblogs.com/sbhyc/p/10566225.html