Go 知识iota

Go 知识iota

  • [1. 介绍](#1. 介绍)
  • [2. 特性](#2. 特性)
  • [3. 原理](#3. 原理)
  • [4. 你真的理解了吗](#4. 你真的理解了吗)

1. 介绍

iota 是一个预定义的标识符,用于声明枚举常量。它在 const 声明中使用,表示连续的未类型化整数。其值从0开始,const声明块每增加一行,iota的值就会自增1,即使没有使用也会增加。

2. 特性

  • iota 只能用在cont中使用
  • 每当遇到cont关键字,iota就会被重置为0
  • iota代表了cont声明的行索引
  • const中的声明如果没有指定值,那么等于iota的值
  • iota可以和表达式使用
  • const声明中没有指定值,继承上一行的值的时候,会进行继承,继承的时候也会继承表达式

举例:

Go 复制代码
import (
	"fmt"
	"testing"
)

const (
	index0, value0, express0 = iota, iota, iota + 1
	index1, value1, express1                         // 继承
	_, _, _                                          // iota 表示行索引,这里什么也不赋值,只是增加行索引
	index3, value3, express3                         // 继承
	index4, value4, express4 = iota, iota, iota * 10 // 修改表达式
	index5, value5, express5                         // 继承
	// 空行,iota 不会加,注释不参与代码逻辑
	index6, value6, express6 = -1, -1, -1 // 没有使用也会加
	index7, value7, express7 = iota, iota, iota * 3
)
const (
	// 空行,iota 不会加,注释不参与代码逻辑
	index, value, express = iota, iota, iota * 3 // 重置
)

func TestIota(t *testing.T) {
	fmt.Println(index0, value0, express0)
	fmt.Println(index1, value1, express1)
	fmt.Println(index3, value3, express3)
	fmt.Println(index4, value4, express4)
	fmt.Println(index5, value5, express5)
	fmt.Println(index6, value6, express6)
	fmt.Println(index7, value7, express7)
	fmt.Println(index, value, express)
}

3. 原理

iota标识符仅能用于常量声明语句中,iota的取值与常量声明块中的代码的行数强相关。

可以发现在常量的声明块中,一行可以声明多个常量,但是在一个常量块中,每行的常量数量必须一致。

如果凑不足,可以使用_占位。

仔细研究常量块,可以发现常量在编译中的表示,可以近似如下理解:

Go 复制代码
type ConstMeta struct {
	Doc     *string // 单行注释,也就是空行
	Names   []*string // 每行有多少个常量的名字
	Type    string // 常量的类型 , 有可能为空,表示值类型,一般只有表达式这个才有效
	Values  []*interface{} // 常量的值
	Comment *string // 行内注释
}

一个常量块有多少行,就会有多少个ConstMeta,需要注意的是,单行注释会和下面的常量定义合并在一起。

类似的伪代码可以如下:

Go 复制代码
	for iota, meta := range consts {
		for i, name := range meta.Names {
			tmp := *name + strconv.Itoa(iota)
			meta.Values[i] = &tmp
		}
	}

所以iota会存在如下特征:

  • 单个const块从0开始
  • const块中每增加一行,iota的值就加1,即使没有使用iota也会增加
  • 单行声明中,即使出现多个iota的使用,iota的值也不变

4. 你真的理解了吗

  • Go 标准库syslog,日志级别。
Go 复制代码
type Priority int

const (
	LOG_EMERG Priority = iota
	LOG_ALTER
	LOG_CRIT
	LOG_ERR
	LOG_WARNNING
	LOG_NOTICE
	LOG_INFO
	LOG_DEBUG
)
  • Go 标准库 sync ,互斥锁的状态。
Go 复制代码
const (
	mutexLocked = 1 << iota // mutex is locked
	mutexWoken
	mutexStarving
	mutexWaiterShift = iota
	starvationThresholdNs = 1e6
) 
相关推荐
明月_清风8 小时前
从二叉树到 B+ 树:一文搞懂工程中「树」的演化之道
数据结构·算法·go
江湖十年9 小时前
在 Go 中使用 dyno 包处理动态对象
后端·面试·go
a187927218319 小时前
【算法】回溯算法(三):三记重锤与 N 皇后——记忆化、状态设计与三层漏斗
算法·leetcode·go·剪枝·回溯·n皇后·算法讲解
纪卓志George10 小时前
打破语言范式:在 Go 里用动态代理实现 AOP
架构·go
平头哥AI10 小时前
Day 01 | go run 跑通第一个 Go 程序,go build 留下一个能拷走的 exe
开发语言·后端·golang
2601_9622965112 小时前
如何使用Golang包路径_管理本地和远程模块引用
golang·数据转换·变量定义·常用库·编程语言区别
FfHUCisI16 小时前
GMP 调度器:Go 并发的心脏是如何跳动的
开发语言·golang·php
我不会起名字32217 小时前
一天一道算法题(26):栈的简单应用
java·数据结构·python·算法·leetcode·golang·
码艺-Alimjan17 小时前
维吾尔语数字转文本
java·javascript·python·算法·go
gsls20080817 小时前
告别 Vault 的复杂度:用 Go 标准库给 Windows 凭据管理器装上 MCP
windows·golang·mcp