常量 - Go 语言学习笔记

267 阅读3分钟

Go语言常量的定义

常量是一种表达式,在程序编译阶段就计算出其值,在程序运行时无法改变该值,从而使编译器得以知晓其值(编译优化),减少运行时的错误,提升运行时的性能。

所有常量的数据类型都属于基本类型:布尔型、数字型(整数型、浮点型和复数)和字符串型。

常量作为操作数时,所有算术运算、逻辑运算和比较运算的结果依然是常量,常量的类型转换结果和某些内置函数的返回值,例如len、cap、real、imag、complex和unsafe.Sizeof,同样是常量。

Go语言常量的声明

常量的声明格式:

const identifier [type] = value

可以省略类型说明符 [type],因为编译器可以根据右边的表达式来推断其类型。

  • 显式类型定义: const b string = "abc"

  • 隐式类型定义: const b = "abc"

多重赋值的声明可以简写为:

const c_name1, c_name2 = value1, value2

批量声明常量:

const (
    Unknown = 0
    Female = 1
    Male = 2
)

Go语言常量的应用

因为常量是在编译器确定的,因此可以作为一些复杂类型的组成部分,比如数组类型的长度:

const IPv4Len = 4
var p [IPv4Len]byte

因为常量作为操作数时返回结果仍然为常量,因此常量可以用len()、cap()、 unsafe.Sizeof()函数计算表达式的值。常量表达式中,函数必须是内置函数,否则编译不过:

import "unsafe"
const (
    a = "abc"
    b = len(a)
    c = unsafe.Sizeof(a)
)
fmt.Println(a, b, c) // abc 3 16

批量声明常量时,除了第一个常量,其它常量声明时的右边表达式都可以省略。如果某个常量的右边表达式缺失,则该常量的值和类型等于前面常量的值和类型,例如:

const (
    a = 1
    b
    c = 2
    d
)
fmt.Println(a, b, c, d) // 1 1 2 2

实际应用中,上面的代码并没有太多实用价值,但是可以利用它实现iota语法。

iota

iota是golang语言的常量计数器,只能在常量的表达式中使用,属于特殊常量,可以认为是一个可以被编译器修改的常量。

iota在const关键字出现时将被重置为0(const内部的第一行之前),const中每新增一行常量声明将使iota计数一次(iota可理解为const语句块中的行索引)。

理解:

  1. iota只能在常量的表达式中使用, 反之 fmt.Println(iota) 编译错误: undefined: iota
  2. 每次 const 出现时,都会让 iota 初始化为0。
const a = iota    // a = 0 
const ( 
  b = iota        // b = 0 
  c               // c = 1 
)

iota 用法

  1. iota 可以被用作枚举值
const (
    a = iota
    b = iota
    c = iota
)
  1. 自定义类型

自增长常量经常包含一个自定义枚举类型,允许你依靠编译器完成自增设置。

type Weekday int
const (
    Sunday Weekday = iota   // 0
    Monday                  // 1
    Tuesday                 // 2
    Wednesday               // 3
    Thursday                // 4
    Friday                  // 5
    Saturday                // 6
)
  1. 可跳过的值

可以使用下划线跳过不想要的值

type AudioOutput int
const ( 
    OutMute AudioOutput = iota  // 0
    OutMono                     // 1
    OutStereo                   // 2
    _                           // iota += 1
    _                           // iota += 1
    OutSurround                 // 5 
)
  1. 使用位掩码表达式定义数量级
const (
    _ = 1 << (10 * iota)
    KiB     // 1024
    MiB     // 1024 * 1024
    GiB     // 1024 * 1024 * 1024
)
  1. 定义在一行的情况 iota 在下一行增长,而不是立即取得它的引用。
const (
    Apple, Banana = iota + 1, iota + 2      // Apple:1, Banana:2 
    Cherimoya, Durian                       // Cherimoya:2, Durian:3
    Elderberry, Fig                         // Elderberry:3, Fig:4
)
  1. 中间插队
const ( 
    i = iota    // i = 0
    j = 3.14    // j = 3.14, iota += 1
    k = iota    // k = 2, iota += 1
    l           // l = 3
)