常量的定义及使用

  1. 常量是一个简单的标识符,运行时不会被修改,没使用的常量在编译时候不会报错(全局变量未使用也不会报错)。
  2. 常量在其他语言一般建议使用全大写字母,但是在 Go 中大写字母开头的表示可导出。
  3. 常量中的数据类型只可以是布尔型(bool)、数值型(整数型、浮点型、复数)和字符串型(string),不能是复合类型。
  4. 不能获取常量的地址(也没必要),如 &aa为常量,常量通常是与代码一起被保存在代码段。
  5. 字符串单个字符也不能取地址如&s[0](sstring类型),字符串是只读类型,在语言层面阻止。
  6. 注意字符串&s&s[0]代表的不是同一个地址的区别。
  7. 字典的单个key也不能取地址&m["o"](mmap类型),字典使用哈希桶形式存储,一个桶存8个key-value。

常量的定义

  1. const identifier [type] = value
    • const:定义常量关键字。
    • identifier:常量名称标识符。
    • [type]:类型,可选。
    • value:常量值。
1
2
// 关键字 标识符 [类型] = 值
const identifier [type] = value
1
2
3
4
5
// 指定类型常量
const IDENTIFIER bool = false   // 显式类型定义

// 无类型常量,推断类型行为bool
const IDENTIFIER = true         // 隐式类型定义

定义多个常量

1
2
// 1. 推断类型 A为bool B为int C为string
const A, B, C = true, 52, "golang"	// 多重赋值
1
2
3
4
5
6
// 2. 
const (
    UNKNOWN = 0 // 推断为int类型
    FEMALE  = 1 // 推断为int类型
    MALE    = 2 // 推断为int类型
)
1
2
3
4
5
6
7
// 同时声明多个常量时,如果省略了值则表示和上面一行的值相同
const (
    A uint16 = 255  // 255
    B               // 255
    C = "hello"     // hello
    D               // hello
)

无类型常量

  1. 没有指明常量类型的常量。const PI = 3.14159
  2. 无类型常量具有默认类型,该类型在需要类型化值得上下文中隐式转换常量的类型:
    • 在简式声明中:i := 0 没有显示类型,这与变量的无类型声明不同。
    • 无类型常量的默认类型分别是 boolruneintfloat64comolex128string
    • 具体决定于它是布尔值、字符、整数、浮点数、复数还是字符串。
  3. 常量的值必须是在编译时就能确定的。
    • 可以在赋值表达式中涉及计算过程,但是所有用于计算的值必须在编译期间就能获得。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import (
    "fmt"
)

func main() {
    const a = 5             // 无类型常量在使用时根据上下文语境转换
    var intVar int = a
    var int32Var int32 = a
    var float64Var float64 = a
    var complex64Var complex64 = a
    fmt.Println(intVar, int32Var, float64Var, complex64Var) // 5 5 5 (5+0i)

    const aa = 5.0
    var intVV int = aa // 浮点数不能默认转int类型
    fmt.Println(intVV) // 5

    //const aaa = 5.1
    //var intVVV int = aaa  // constant 5.1 truncated to integer
    //fmt.Println(intVVV)
}

iota

  1. 特殊常量,可以被编译器修改的常量。
  2. 每遇到const关键字,iota将被重置为0。
  3. 每当 iota 在新的一行被使用时,iota会自动加一,iota++。其实并不是iota在新的一行中出现就会加一,不出现也会自增。
  4. iota的准确定义是】:iota表示const声明块的行索引(下标从0开始),解释就是iota表示当前const的行号,不管使用没使用iota
  5. const还有一个重要的特点是】:第一个常量必须指定一个表达式,后续的常量如果没有表达式,则继承上面的表达式

iota使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
const (
    A = iota    // 0  (iota == 0)	
    B = iota    // 1  (iota == 1)
    C = iota    // 2  (iota == 2)
)

const (
    AA = iota   // 0  (iota == 0)
    BB          // 1  (iota == 1)   等效于 BB = iota
    CC          // 2  (iota == 2)   等效于 CC = iota
)

// 不管conts中是否有使用iota,都是按照行号递增的
const (
    one   = 3       // 3 (iota == 0)
    two   = iota    // 1 (iota == 1)
    three = iota    // 2 (iota == 2)
    four            // 3 (iota == 3)
    five            // 4 (iota == 4)
)

type CAPACITY uint
const (
    B CAPACITY = 1 << (iota * 10)// 1 == 2^0            (iota == 0)
    // 等效于 KB CAPACITY = 1 << (iota * 10)
    KB                           // 1024 == 2^10        (iota == 1)
    // 等效于 MB CAPACITY = 1 << (iota * 10)
    MB                           // 1024 * 1024 = 2^20  (iota == 2)
)

const (
    D1 = iota       // 0        (iota == 0)
    D2              // 1        (iota == 1) 等效于 D2 = iota
    D3              // 2        (iota == 2) 等效于 D3 = iota
    D4              // 3        (iota == 3) 等效于 D4 = iota
    D5 = "HELLO"    // HELLO    (iota == 4)
    D6              // HELLO    (iota == 5) 等效于 D6 = "HELLO"
    D7 = 23         // 23       (iota == 6)		
    D8              // 23       (iota == 7) 等效于 D7 = 23
    D9 = iota       // 8        (iota == 8)
    D10             // 9        (iota == 9) 等效于 D10 = iota
)

const (
    D1, D2 = 1 << iota, 1 << iota - 1 // 1 0  iota == 0	00000001 << 0 == 0 , 00000001 << 0 - 1 == 0
    // 等效于 D3, D4 = 1 << iota, 1 << iota - 1
    D3, D4                            // 2 1  iota == 1	00000001 << 1 == 2 , 00000001 << 1 - 1 == 1
    // 等效于 D5, D6 = 1 << iota, 1 << iota - 1
    D5, D6                            // 4 3  iota == 2	00000001 << 2 == 4 , 00000001 << 2 - 1 == 3
)

参考

  1. Go高阶指南05,iota 实现原理