Go语言的常量是一种表达式,常量可以保证在编译阶段就计算出表达式的值。所有的常量本质上都属于基本类型:数字、布尔型、字符串等。Go语言的常量定义与变量类似,只不过使用了const关键字修饰,但不能使用短变量声明关键字 := 来定义常量。
对于常量操作数,所有数学运算、逻辑运算和比较运算的结果依然是常量,常量的转换结果和某些内置函数的返回值(例如len、cap、real、imag、complex和unsafe.Sizeof)同样是常量。
常量声明可以同时指定类型和值,如果没有显式指定类型,则类型根据右边的表达式推断。若同时声明一组变量,除了第一项之外,其他项在等号右侧的表达式都可以省略,这意味着会复用前面一项的表达式及其类型。
const (
a = 1
b
c = 2
d
)
fmt.Pritln(a, b, c, d) //1 1 2 2
常量生成器iota
常量的声明可以使用常量生成器iota,它创建一系列相关值,常量声明中iota从0开始取值,逐项加1,这与C++中的枚举型(enumeration)相同。下面是time包中对Weekday类型的定义:
type Weekday int
const (
Sunday Weekday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
上面的声明中,Sunday的值为0,Monday为1,依此类推。
iota结合算术运算还有更复杂的应用,如表示1024的幂:
const (
_ = 1 << (10 * iota)
KB
MB
GB
TB
PB
)
无类型常量
Go语言的常量虽然可以是任何基本数据类型,但许多常量并不从属某一具体类型。编译器将这些从属类型特定的常量表示成某些值,这些值比基本类型的精度更高,且算术精度高于原生的机器精度。可以认为它们的精度至少达到256位。从属类型待定的常量共有6种,分别是无类型布尔、无类型整数、无类型文字符号、无类型浮点数、无类型复数、无类型字符串。
只有常量才可以是无类型的。若将无类型常量声明为变量,或在类型明确的变量赋值的右方出现无类型常量,则常量会被隐式转换为该变量的类型。
var f float64 = 3 + 0i //无类型复数→float64
f = 2 //无类型整数→int
推迟确定从属类型使得无类型常量不仅能暂时维持更高的精度,与类型已确定的常量相比,它们还能写进更多表达式而无须转换类型。以下面的程序为例:
const (
x = 9223372036854775808
y = 20
)
//fmt.Printf("%T\n", x)
fmt.Println(x/y)
变量x的值用哪种整数类型都无法存储,如果输出x的类型则会编译错误并提示:constant 9223372036854775808 overflows int,说明这是一个溢出的整数。但执行x/y却可以编译成功并得出正确结果。
字面值常量的类型由语法决定。0、0.0、0i和'\u0000'都表示相同的常量值,但类型却不同。再比如,除法运算中操作数的类型对除法结果得到的类型会产生影响,因此常量除法表达式中,操作数选择不同的写法会影响结果。
本文部分内容摘自《Go程序设计语言》