💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
### iota `iota`是`go`语言的常量计数器,只能在常量的表达式中使用 使用规则: * iota代表了const声明块的行索引(下标从0开始) 源码: const块中每一行在GO中使用spec数据结构描述,spec声明如下: ~~~GO // A ValueSpec node represents a constant or variable declaration // (ConstSpec or VarSpec production). // ValueSpec struct { Doc *CommentGroup // associated documentation; or nil Names []*Ident // value names (len(Names) > 0) Type Expr // value type; or nil Values []Expr // initial values; or nil Comment *CommentGroup // line comments; or nil } ~~~ 这里我们只关注ValueSpec.Names, 这个切片中保存了一行中定义的常量,如果一行定义N个常量,那么ValueSpec.Names切片长度即为N。 const块实际上是spec类型的切片,用于表示const中的多行。 所以编译期间构造常量时的伪算法如下: ~~~GO for iota, spec := range ValueSpecs { for i, name := range spec.Names { obj := NewConst(name, iota...) //此处将iota传入,用于构造常量 ... } } ~~~ 从上面可以更清晰的看出iota实际上是遍历const块的索引,每行中即便多次使用iota,其值也不会递增 #### 示例一 使用_跳过某些值 ~~~ const ( n1 = iota //0 n2 //1 _ n4 //3 ) ~~~ `iota`声明中间插队 ~~~ const ( n1 = iota //0 n2 = 100 //100 n3 = iota //2 n4 //3 ) const n5 = iota //0 ~~~ 定义数量级 (这里的`<<`表示左移操作,`1<<10`表示将`1`的二进制表示向左移`10`位,也就是由`1`变成了`10000000000`,也就是十进制的`1024`。同理`2<<2`表示将`2`的二进制表示向左移`2`位,也就是由`10`变成了`1000`,也就是十进制的`8`。) ~~~ const ( _ = iota KB = 1 << (10 * iota) MB = 1 << (10 * iota) GB = 1 << (10 * iota) TB = 1 << (10 * iota) PB = 1 << (10 * iota) ) ~~~ 多个`iota`定义在一行 ~~~ const ( a, b = iota + 1, iota + 2 //1,2 c, d //2,3 e, f //3,4 ) ~~~ #### 示例二 ~~~go const ( mutexLocked = 1 << iota // mutex is locked mutexWoken mutexStarving mutexWaiterShift = iota starvationThresholdNs = 1e6 ) ~~~ 题目解释: 以上代码取自Go互斥锁Mutex的实现,用于指示各种状态位的地址偏移。 参考答案: mutexLocked == 1;mutexWoken == 2;mutexStarving == 4;mutexWaiterShift == 3;starvationThresholdNs == 1000000 #### 示例三 ~~~go const ( bit0, mask0 = 1 << iota, 1<<iota - 1 bit1, mask1 _, _ bit3, mask3 ) ~~~ 参考答案: bit0 == 1, mask0 == 0, bit1 == 2, mask1 == 1, bit3 == 8, mask3 == 7