Go语言中的常量使用关键字const定义,用于存储不会改变的数据,常量是在编译时被创建的,即使定义在函数内部也是如此,并且只能是布尔型、数值型(整型、浮点型和复数类型)和字符串型。由于编译时的限制,定义常量的表达式必须为能被编译器求值的常量表达式。
1、常量的定义
常量是在程序运行时不会被修改的量。常量的定义格式如下:const identifier [type] = value
- 译器可以根据变量的值来推断其类型,因此可以省略类型说明符
[type]
。
Go语言中常量的定义包括显式定义和隐式定义两种:
- 显式定义如下:
const a string = "apple"
- 隐式定义如下:
const a = "apple"
const Pi = 3.1415926 //可以指定常量的类型
const Pi float32=3.1415926 //也可以是布尔值、字符串等
const hello="Go语言" //还可以使用中
Go语言的常量还可以是十进制、八进制或十六进制的常数。
- ① 十进制无前缀。
- ② 前缀为0的是八进制。
- ③ 前缀为0x或0X的是十六进制。
- ④ 另外,整数还可以有一个后缀,其后缀可以是大小写字母(顺序任意)。后缀通常是U和L的组合,通常用于表示unsigned和long。
3.1415926 //十进制,合法
0215 //八进制,合法
0x25 //十六进制,合法
30u //无符号整型,合法
25l //long,合法
25ul //无符号long,合法
2、常量的声明
常量的声明和变量的声明类似,只是把var换成了const。多个变量可以一起声明,同样,多个常量也可以一起声明:
const (
e = 2.7182
pi = 3.1415
)
在Go语言中,所有常量的运算都可以在编译期来完成,这样不仅可以减少运行时的工作,也方便其他代码的编译优化。当操作数是常量时,运行时经常出现的错误也可以在编译时被发现,例如,整数除零、字符串索引越界、任何导致无效浮点数的操作等。
常量间的所有算术运算、逻辑运算和比较运算的结果也是常量,对常量的类型转换操作或函数调用(len、cap、real、imag、complex和unsafe.Sizeof)都是返回常量结果。
由于常量的值是在编译期就确定的,因此常量可以用于数组的声明:var arr [size] int
如果是批量声明的常量,除了第一个常量外,其他的常量右边的初始化表达式都可以省略。如果省略初始化表达式,则表示使用前面常量的初始化表达式,对应的常量类型也是一样的:
const (
a =3
b
c =5
d
)
fmt.Println(a, b,c, d) //"3 3 5 5"
特殊常量:iota
在Go语言中有一个特殊的常量——iota。iota是一个可以被编译器修改的常量。
iota在const关键字出现时将被重置为0,const中每新增一行常量声明将使iota计数一次。
iota可以被用作枚举值,例如:
const (
a = iota
b = iota
c = iota
)
第一个iota等于0,每当iota在新的一行被使用时,它的值都会自动加1;所以a=0, b=1, c=2可以简写为如下形式:
const (
a = iota
b
c
)
3、转义字符
和其他语言一样,Go语言也使用反斜杠表示转义字符。常用的转义字符及其含义如下表:
package main
import "fmt"
func main() {
fmt.Println("hello\tworld!")
fmt.Println("hello\rworld!")
}
4、赋值
Go语言支持直接赋值运算符、相加和赋值运算符、相减和赋值运算符、相乘和赋值运算符、相除和赋值运算符、左移和赋值运算符、右移和赋值运算符、按位与和赋值运算符、按位异或和赋值运算符、按位或和赋值运算符等。
package main
import "fmt"
func main() {
a := 10
c := 20
c = a
fmt.Println("将a赋值给c,c的值为:", c) // 10
c += a
fmt.Println("将a相加和赋值给c,c的值为:", c) // 20
c -= a
fmt.Println("将a相减和赋值给c,c的值为:", c) // 10
c *= a
fmt.Println("将a相乘和赋值给c,c的值为:", c) // 100
c /= a
fmt.Println("将a相除和赋值给c,c的值为:", c) // 10
c <<= 2
fmt.Println("将c左移2位,c的值为:", c) // 40
c >>= 2
fmt.Println("将c右移2位,c的值为:", c) // 10
c &= 2
fmt.Println("按位与和赋值,c的值为:", c) // 2
c ^= 2
fmt.Println("按位异或和赋值,c的值为:", c) // 0
c |= 2
fmt.Println("按位或和赋值,c的值为:", c) // 2
}
5、枚举
常量还可以用作枚举。
const (
Connected = 0
Disconnected =1
Unknown =2
)
- 数字0表示连接成功;数字1表示连接断开;数字2表示未知状态。
枚举类型的实现需要使用iota关键字:
package main
import "fmt"
const (
a = iota // 0
b // 1
c // 2
d, e, f = iota, iota, iota // 3, 3, 3
g = iota //4
h = "h" // h
i // h
j = iota // 7
)
const z = iota // 0
func main() {
fmt.Println(a, b, c, d, e, f, g, h, i, j, z)
}
- b==1,隐式使用iota关键字,等同于b=iota
- d=3,e=3,f=3,同一行值相同
- h =="h"单独赋值,iota递增为5
- i =="h",默认使用上面的赋值,iota递增为6
- j == 7
- 每个单独定义的const常量中,iota都会重置,此时z==0
每个const定义的第一个常量被默认设置为0,显式设置为其他值除外。后续的常量默认设置为它上面那个常量的值,如果前面那个常量的值是iota,则它也被设置为iota。由于iota可以实现递增,因此它也可以实现枚举操作。另外,iota还可以在表达式中使用。
注意:当遇到d, e, f = iota, iota, iota这种情况时,虽然同一行值相同,但不能省略其他iota,书写完整才是正确的。