美文网首页Tips
Go 语言枚举值

Go 语言枚举值

作者: Sun东辉 | 来源:发表于2022-05-23 16:46 被阅读0次

    首先,我们看一段代码:

    const (
        x = iota
        y
        z = "zz"
        k
        p = iota
    )
    
    func main() {
        fmt.Println(x, y, z, k, p)   // 0 1 zz zz 4
    }
    
    

    为什么会这样?

    首先,我们分析 k 为什么是 “zz”?

    const 声明有个重要特点,第一个常量必须指定一个表达式,后续的常量如果没有表达式,则继承上面的表达式。这里 k 的前一个表达式为 “zz”,所以 k 的值为 “zz”。

    现在,我们再来看看 p 为什么是 4? 其实,这和 go 语言底层的实现有关,const 块中每一行在 Go 中使用 spec 数据结构描述, spec 声明如下:

    ValueSpec struct {
            Doc     *CommentGroup // associated documentation; or nil
            Names   []*Ident      // value names (len(Names) > 0) 保存了一行中定义的常量,如果一行定义 N 个常量,那么 ValueSpec.Names 切片长度即为 N。
            Type    Expr          // value type; or nil
            Values  []Expr        // initial values; or nil
            Comment *CommentGroup // line comments; or nil
    }
    Ident struct {
            NamePos token.Pos // identifier position
            Name    string    // identifier name
            Obj     *Object   // denoted object; or nil
    }
    
    

    编译期构造常量的伪代码如下:

    for index, value := range ValueSpecs {
            for _, ident := range value.Names {
                    obj := NewConst(ident.name, index, value...) // 此处将 i 值传入,用于构造常量
                     ...
            }
    }
    
    

    可以看出,iota 的值其实是通过它的索引推导出来的,即 const 声明块中每新增一行 iota 值自增 1,这里初始化的 iota 为 0,p 的索引为 4,`0 + 4 = 4`,所以 p 的值为 4。

    相关文章

      网友评论

        本文标题:Go 语言枚举值

        本文链接:https://www.haomeiwen.com/subject/wfnrprtx.html