枚举iota的示例

举报
码乐 发表于 2025/04/13 10:55:35 2025/04/13
【摘要】 Iota 基本示例iota 关键字表示连续的整数常量 0、1、2,…每当单词出现在源代码中时,它就会重置为 0,const并在每个 const 规范之后递增。本文将介绍几种不同的 iota 使用方式,以及有关在何处谨慎使用它的提示。const ( C0 = iota C1 = iota C2 = iota ) fmt.Println(C0, C1, C2) // "0 1 2"这可以...

Iota 基本示例

iota 关键字表示连续的整数常量 0、1、2,…
每当单词出现在源代码中时,它就会重置为 0,const并在每个 const 规范之后递增。
本文将介绍几种不同的 iota 使用方式,以及有关在何处谨慎使用它的提示。

const (
		C0 = iota
		C1 = iota
		C2 = iota
	)
	fmt.Println(C0, C1, C2) // "0 1 2"

这可以简化为

	const (
		C0 = iota
		C1
		C2
	)

在这里,我们依赖于表达式隐式重复的事实 在带括号的 const 声明中 – 这表示重复 的表达式及其类型。

2 从一个开始

要从 1 而不是 0 开始常量列表,可以在算术表达式中使用。iota

	const (
		C1 = iota + 1
		C2
		C3
	)
	fmt.Println(C1, C2, C3) // "1 2 3"

3 跳过值

您可以使用空白标识符跳过常量列表中的值。

	const (
		C1 = iota + 1
		_
		C3
		C4
	)
	fmt.Println(C1, C3, C4) // "1 3 4"

使用字符串完成枚举类型 ,以下是实现枚举类型的惯用方法:

创建一个新的整数类型,使用 列出其值 ,iota为类型String指定一个函数。

	type Direction int

	const (
		North Direction = iota
		East
		South
		West
	)

	func (d Direction) String() string {
		return [...]string{"North", "East", "South", "West"}[d]
	}

使用:

	var d Direction = North
	fmt.Print(d)
	switch d {
	case North:
		fmt.Println(" goes up.")
	case South:
		fmt.Println(" goes down.")
	default:
		fmt.Println(" stays put.")
	}
	// Output: North goes up.

命名约定
标准命名约定是对常量也使用混合大写字母。 例如,导出的是常量 , 而不是 North West NORTH_WEST

4 完整形式

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

  func main() {
      fmt.Println(a)
      fmt.Println(b)
      fmt.Println(c)
  }
  • 省略形式

    const (
        a = iota // 0
        b        // 1
        c        // 2
         )
    
    func main() {
        fmt.Println(a, b, c)
    }
    
  • 顺序

忽略0

  const (
      _ = iota      // 0
      b = iota * 10 // 1 * 10
      c = iota * 10 // 2 * 10
  )

  func main() {
      fmt.Println(b,c)
      //fmt.Println(c)
      }

5 多段定义

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

    const (
        d = iota // 0
        e        // 1
        f        // 2
    )

    字节大小容量

    const (
        a_          = iota // ignore first value by assigning to blank identifier
        KB ByteSize = 1 << (10 * iota)
        MB
        GB
        TB
        PB
        EB
        ZB
        YB
    )

    func main() {
        fmt.Println(a, b, c, d, e, f)
        //fmt.Println(b)
        //fmt.Println(c)
        //fmt.Println(d)
        //fmt.Println(e)
        //fmt.Println(f)
        fmt.Println(a_, KB, MB, GB, TB, PB, EB, ZB, YB)
    }

Iota 是在 Go 中创建递增常量的有用概念。但是,iota 可能不适合在几个领域使用。

6 字节大小的示例

通过位移位数方便地表示字节大小。

const (
    read   = 1 << iota // 00000001 = 1
    write              // 00000010 = 2
    remove             // 00000100 = 4

    // admin will have all of the permissions
    admin = read | write | remove
)

func main() {
    fmt.Printf("read =  %v\n", read)
    fmt.Printf("write =  %v\n", write)
    fmt.Printf("remove =  %v\n", remove)
    fmt.Printf("admin =  %v\n", admin)
}

这样,我们可以看到我们打印出了位掩码值:

$ go run main.go

read =  1
write =  2
remove =  4
admin =  7

更进一步,使用它来计算内存大小等内容。例如,让我们看看以下一组常量:

const (
    KB = 1024       // binary 00000000000000000000010000000000
    MB = 1048576    // binary 00000000000100000000000000000000
    GB = 1073741824 // binary 01000000000000000000000000000000
)

这可以通过使用 shift 运算符和乘数来重写iota

  const (
      _  = 1 << (iota * 10) // ignore the first value
      KB                    // decimal:       1024 -> binary 00000000000000000000010000000000
      MB                    // decimal:    1048576 -> binary 00000000000100000000000000000000
      GB                    // decimal: 1073741824 -> binary 01000000000000000000000000000000
  )

这将产生以下值:

KB = 1024
MB = 1048576
GB = 1073741824

完整形式

const (
    _  = iota             // 0
    KB = 1 << (iota * 10) // 1 << (1 * 10)
    MB = 1 << (iota * 10) // 1 << (2 * 10)
    GB = 1 << (iota * 10) // 1 << (3 * 10)
    TB = 1 << (iota * 10) // 1 << (4 * 10)
)

  func main() {

      fmt.Println("binary\t\tdecimal")
      fmt.Printf("%b\t", KB)
      fmt.Printf("%d\n", KB)
      fmt.Printf("%b\t", MB)
      fmt.Printf("%d\n", MB)
      fmt.Printf("%b\t", GB)
      fmt.Printf("%d\n", GB)
      fmt.Printf("%b\t", TB)
      fmt.Printf("%d\n", TB)

  }

7 在令牌包使用iota

一个领域是 Go 中的令牌包。他们使用了几个聪明技巧来验证常量。

例如,我们可以看到它们使用几个标识符来表示一组常量值的。

literal_beg
// Identifiers and basic type literals
// (these tokens stand for classes of literals)
IDENT  // main
INT    // 12345
FLOAT  // 123.45
IMAG   // 123.45i
CHAR   // 'a'
STRING // "abc"
literal_end

有一个函数来验证该范围内的任何值:

func (tok Token) IsLiteral() bool { return literal_beg < tok && tok < literal_end }

这些值都不会导出,因此无需担心常量值的未来变化。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。