常量
常量(const)是一个简单值的标识符,在程序运行时不会被修改的量。
常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。
const 是 constant 的缩写,表示程序中不可变的值
基本定义格式
const identifier [type] = value
- identifier:常量名称,遵循 Go 标识符命名规则(字母、数字、下划线,且不能以数字开头)
- type(可选):类型名,如果省略则由编译器自动推断
- value:常量的值
定义方式
// 显式类型定义
const b string = "abc"
// 隐式类型定义,类型自动推断
const b = "abc"
// 批量定义,多重赋值
const c_name1, c_name2 = value1, value2
基础常量定义示例
package main
import "fmt"
func main() {
const LENGTH int = 10
const WIDTH int = 5
var area int
const a, b, c = 1, false, "str" // 多重赋值,一次定义多个不同类型的常量
area = LENGTH * WIDTH
fmt.Printf("面积为 : %d\n", area)
fmt.Println(a, b, c)
}
常量组与枚举
Go 语言没有枚举(enum)关键字,通常使用常量组来实现枚举效果:
package main
import "fmt"
// 定义性别枚举
const (
Unknown = 0
Female = 1
Male = 2
)
func main() {
fmt.Printf("未知=%d, 女性=%d, 男性=%d\n", Unknown, Female, Male)
}
常量组缺省值
定义常量组时,如果不提供初始值,则表示将使用上一行的表达式(常量值缺省时取前一个声明的值):
const (
a = 1
b // 没有初始化,使用上一行(即a)的值 1
c // 1
d // 1
)
内置函数在常量中的应用
常量表达式中可以使用 len()、cap()、unsafe.Sizeof() 等内置函数计算表达式的值。
注意:常量表达式中函数必须是内置函数
package main
import (
"fmt"
"unsafe"
)
const (
a = "abc"
b = len(a) // len() 获取字符串长度,结果为 3
c = unsafe.Sizeof(a) // unsafe.Sizeof() 获取内存占用,64位系统字符串占16字节
)
func main() {
fmt.Printf("a=%s, b=%d, c=%d\n", a, b, c)
}
iota 常量计数器
iota 是 Go 语言的特殊常量,也叫常量计数器,可以在 const 声明块中自动生成递增的序列值。
- iota 在 const 关键字出现时被重置为 0
- const 中每新增一行常量声明,iota 自动计数加 1
- 可以理解为 const 语句块中的行索引(从 0 开始)
- iota 只在同一个 const 常量组内递增,每当有新的 const 关键字时,iota 计数重新开始
package main
import "fmt"
// iota 从 0 开始,每行加 1
const (
a = iota // 0
b // 1(省略值,默认使用上一行的 iota)
c // 2
)
func main() {
fmt.Printf("a=%d, b=%d, c=%d\n", a, b, c)
}
iota 详细用法
package main
import "fmt"
func main() {
const (
a = iota // 0
b // 1
c // 2
d = "ha" // 独立值,iota += 1
e // "ha",iota += 1
f = 100 // 独立值,iota += 1
g // 100,iota += 1
h = iota // 7,恢复使用 iota 值
i // 8
)
fmt.Printf("a=%d, b=%d, c=%d, d=%s, e=%s, f=%d, g=%d, h=%d, i=%d\n", a, b, c, d, e, f, g, h, i)
}
要点:
- 当显式赋值时,使用该值,但 iota 仍然递增
- 当省略赋值时,使用上一行的值
- iota 可以插队,恢复使用时是当前的计数值
iota 与位移运算
package main
import "fmt"
const (
i = 1 << iota // 1 << 0 = 1
j = 3 << iota // 3 << 1 = 6
k // 3 << 2 = 12
l // 3 << 3 = 24
)
func main() {
fmt.Printf("i=%d, j=%d, k=%d, l=%d\n", i, j, k, l)
}
x << n 等价于 x * 2^n。如 3 << 2,二进制 11 变 1100,即 12
iota 在同一个 const 常量组内递增,新的 const 关键字出现时 iota 重新从 0 开始
常量与变量的区别
| 特性 | 常量(const) | 变量(var) |
|---|---|---|
| 值是否可变 | 定义后不可修改 | 可以随时重新赋值 |
| 初始化 | 必须要有初值 | 可以只声明不定义,取零值 |
| 可用类型 | 布尔、数字、字符串 | 任意类型 |
| 命名习惯 | 名称尽量用大写 | 常规驼峰命名 |