目录
常量
常量表示程序运行时恒定不可改变的值,通常是一些字面量。常量使用一个名称来绑定一块内存地址,该内存地址中存放的数据类型由定义常量时指定的类型决定,常量存储在程序的只读段中,因此该内存地址里存放的内容不可以改变。使用常量可以提高程序的阅读性和可维护性,因为这就避免了“魔法数字”的使用,也无须修改所引用的代码。
声明
声明一个常量由一个常量名constant_name,可选的常量类型和常量值组成。
const <constant_name> [<constant_type>] = <value>
如果显示指定类型,必须确保常量左右值类型一致,需要时可做显示转换。例如声明一个整型常量age:
const age int = 15
右值不能超出常量类型取值范围,否则会引发溢出错误。
const number int = 99999999999999999999 // constant 99999999999999999999 overflows int
省略常量类型时,编译器会自行判断。其中整型数值默认的类型为int,浮点数值默认的类型为float64。
const i, f = 1, 0.123 // int, float64
多个常量声明可以由一个括号包裹:
const (
x, y int = 123, 0x22
f = 0.123
)
不可以在相同作用域下声明同名常量,但可以在不同作用域下声明。
package main
const (
x = 123
x = 456 // 相同作用域下定义重名常量,编译器报错:x redeclared in this block
)
func main() {
const x = 456
}
与变量名类似,首字母是大写的常量名可以被包外引用,而首字母是小写的常量名只能在包内使用。因此对于一些私有的常量,不想被包外访问,我们可以将其首字母小写。
package demo
const (
x = 123 // 只能在包内使用
X = 456 // 可以在包外使用,也可以在包内使用
)
常量的值
Go中常量分为布尔型、字符型、字符串型和数值型,即常量值必须是编译期可确定的字符、字符串数字或布尔型。可指定常量类型,或由编译器通过初始化值推断。常量存储在程序的只读段(.rodata section)中。
// 显示指定常量类型
const x, y int = 12345, 0x22
// 编译期初始化值推断
const s = "hello world!"
// 常量支持unicode字符(rune)
const c = '好'
常量值可以是某些编译器能计算出结果的表达式:
const length = len("hi")
在常量组中如不指定类型和初始化值,则与上一行非空常量右值(表达式文本)相同(值和类型都相同)。
const (
a = len("hi") // 2
b // 2
c // 2
d = 100 // 100
e // 100
)
声明位置
通常情况下,常量在函数外声明:
package main
const Host = "localhost"
func function() {}
但也可以在函数内定义常量:
package main
import "fmt"
const Host = "localhost"
func main() {
const Host = "192.168.0.1"
fmt.Println("host:", Host)
// output: host: 192.168.0.1
}
💡提示:不曾使用的常量不会引发编译错误。
枚举
iota的作用
Go没有明确意义上的enum定义,不过可以借助iota标识符实现一组自增常量值来实现枚举类型。
const (
a = iota // 0
b // 1
c // 2
)
iota可以参与到表达式中计算:
const (
_ = iota // 0
A = 3 * iota // 3 * 1
B // 3 * 2
C // 3 * 3
)
iota自增范围
自增作用范围为常量组。可在多常量定义中使用多个iota,它们各自单独计数,只须确保组中每行常量的列数量相同即可。
const (
_, _ = iota, iota * 10 // 0, 0 * 10
a, b // 1, 1 * 10
c, d // 2, 2 * 10
)
如果自增常量的列数量不相同,则编译报错:extra expression in const declaration.
const (
_, _ = iota, iota * 10
a, b
d = 2
c // extra expression in const declaration
)
自增范围仅多用于当前常量组中:
const (
a = iota // 0
b // 1
c // 2
)
const (
d = 100 // 100
e = iota // 1
f // 2
)
iota自增中断
如中断iota自增,则必须显式恢复。且后续自增值按行序递增。
const (
a = iota // 0
b // 1
c = 100 // 100 (显式赋值,自增中断)
d // 100 (与c常量右值表达式相同)
e = iota // 4 (恢复iota自增,按行序递增,计数包括c, d)
f // 5
)
iota数据类型
自增默认的数据类型是int,可显式指定类型。
const (
id = iota // int, 值为0
high float64 = iota // float64, 值为1
score // float64, 值为2
age = iota // 显示指定iota, 数据类型为int, 值为3
)