Go:变量、常量、枚举
一、变量
package main import "fmt" func variableZeroValue() { // 变量声明 var a int var b string fmt.Println(a, b) // 0 fmt.Printf("%d %q\n", a, b) // 0 "" } func variableInitialValue() { // 变量初始化 var a, b = 1, 2 // 编译器可以自动推导出变量的类型 c, d := 1, "pd" // 使用:=定义变量(只能在函数内使用) a = 10 // 赋值不能使用 a := 10 a, b = b, a // 变量交换 fmt.Println(a, b, c, d) } //在函数外定义变量,不能使用 := var a = 10 var b = 20 // 上面方式可以这样 var ( c = 30 d = 40 ) func main() { variableZeroValue() variableInitialValue() fmt.Println(a, b, c, d) }
- 变量类型写在变量名之后;
- 编译器可以推测变量所属类型;
- 没有char,只有rune;
- 原生支持复数类型。
二、常量
在Go语言中,常量是指编译期间就已知且不可改变的值。常量可以是数值类型(包括整型、浮点型和复数类型)、布尔类型、字符串类型等。
一个常量的声明语句定义了常量的名字,和变量的声明语法类似,常量的值不可修改,这样可以防止在运行期被意外或恶意的修改。
2.1 字面常量
所谓字面常量(literal),是指程序中硬编码的常量,如:
-12 3.1415926 // 浮点类型的常量 3.2+12i // 复数类型的常量 true // 布尔类型的常量 "foo" // 字符串常量
2.2 常量定义
通过const关键字,可以给字面常量指定一个名字:
func constDefine() { // 定义常量 /* 常量定义可以限定常量类型,但不是必需的。 如果定义常量时没有指定类型,那么它与字面常量一样,是无类型常量。 */ const pi = 3.1415926 const zero = 0.0 // 无类型浮点常量 const ( size int64 = 1024 xx = -1 // 无类型整型常量 ) const a, b float32 = 1, 2 // 常量的多重赋值 const c, d, e = 3, 4, "foo" fmt.Println(pi, zero, size, xx, a, b, c, d, e) }
2.3 预定义常量
Go语言预定义了这些常量:true、false和iota。
iota比较特殊,可以被认为是一个可被编译器修改的常量,在每一个const关键字出现时被重置为0,然后在下一个const出现之前,每出现一次iota,其所代表的数字会自动增1。
func func1() { const ( // iota被重设为0 c0 = iota // c0 == 0 c1 = iota // c1 == 1 c2 = iota // c2 == 2 ) fmt.Println(c0, c1, c2) // 0 1 2 const ( a11 = 1 << iota // a11 == 1 (iota在每个const开头被重设为0) b11 = 1 << iota // b11 == 2 c11 = 1 << iota // c11 == 4 ) fmt.Println(a11, b11, c11) // 1 2 4 /* 如果两个const的赋值语句的表达式是一样的,那么可以省略后一个赋值表达式; 因此,上面的前两个const语句可简写为: */ const ( c00 = iota c01 c02 ) const ( a22 = 1 << iota b22 = 1 << iota c22 = 1 << iota ) const ( b = 1 << (10 * iota) kb mb gb ) fmt.Println(b, kb, mb, gb) // 1 1024 1048576 1073741824 }
三、枚举
枚举指一系列相关的常量,比如下面关于一个星期中每天的定义。通过上一节的例子,我们看到可以用在const后跟一对圆括号的方式定义一组常量,这种定义法在Go语言中通常用于定义枚举值。Go语言并不支持众多其他语言明确支持的enum关键字。
下面是一个常规的枚举表示法,其中定义了一系列整型常量:
func enum() { const ( Sunday = iota Monday Tuesday Wednesday Thursday Friday Saturday numberOfDays // 这个常量没有导出 ) fmt.Println(Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday) // 0 1 2 3 4 5 6 }
同Go语言的其他符号(symbol)一样,以大写字母开头的常量在包外可见。
以上例子中numberOfDays为包内私有,其他符号则可被其他包访问。