二、变量与常量
变量与常量,是从数学中借鉴过来的,用来描述计算机存储计算结果或表示值的抽象概念。通常在计算机中,用前面我们学过的标识符来命名设定。
变量,毫无疑问,就是可以改变的量,它被定义后可以不给设置初始值,其变量值在程序中还可以被修改。然而,常量,就不是可以发生改变的量,它一旦被定义后必须设置初始值,而且更重要的是常量值不允许被修改。
2.1、变量的定义与赋值
在Go语言中,变量由var关键字定义,并且有5种不同的定义方式,具体如下所示:
// 第一种方式:只定义变量,不初始化,之后再赋值
var age int
age = 31
// 第二种方式:定义变量并初始化初始值
var name string = "Jack"
// 第三种方式:批量定义多个变量,每个变量根据情况决定是否赋初始值
var(
num01 int = 90
weight float64
)
// 第四种方式:多个变量属于同一数据类型
var num02,num03 int = 10,20
// 第五种方式:自动推导类型(:=),通过变量的值反过来推导变量的类型
height := 2.37
2.2、常量与iota
在Go语言中,我们使用关键字const来定义常量,然而,常量的定义有四种不同的方式。如下所示:
package main
import "fmt"
func main() {
// 第一种方式:声明并初始化
const Age int = 30
// 第二种方式:定义单个常量,可以省略常量类型
const name = "tony"
// 第三种方式:小括号定义多个常量
const (
num01 int = 31
num02 = 33
)
// 第四种方式:使用逗号定义多个常量
const num03, num04 = 10, 20
// 打印输出常量值
fmt.Println("Age =", Age)
fmt.Println("name =", name)
fmt.Println("num01 =", num01)
fmt.Println("num02 =", num02)
fmt.Println("num03 =", num03)
fmt.Println("num04 =", num04)
}
运行上述代码,运行结果如图2-1所示
上面,我们知道,常量一旦被定义,就没法被修改,但是,也有特俗的常量iota,它是一个可以被编译器修改的常量。那么它又有什么特性呢?
iota在关键字const出现时将被重置为0,如果关键字const定义多个常量,iota会自动为每个常量进行计数累加,如下面的代码所示:
package main
import "fmt"
func main() {
const (
a = iota // iota设为0,常量a的值为iota的值
b // iota累加为1
c // iota累加为1
d = 30 // iota累加为1,常量d的值为30
e // iota累加为1,常量e的值为30
f = iota // iota累加为1,常量e的值为iota的值
)
fmt.Printf("a的值为:%d\n", a)
fmt.Printf("b的值为:%d\n", b)
fmt.Printf("c的值为:%d\n", c)
fmt.Printf("d的值为:%d\n", d)
fmt.Printf("e的值为:%d\n", e)
fmt.Printf("f的值为:%d\n", f)
}
运算上述代码,结果为图2-2所示。
综合上述代码和运行结果分析可以知道下面几个要点。
1、使用关键字const定义多个常量,关键字const是从0开始计算,之后,每增加一个常量就会使iota自动增加1。
2、如果常量值设定为iota的值,且下一个常量没有赋值,那么没有被赋值的常量会与它上一个常量值相同。如上述代码中的b、c没有赋值,它们上一个常量a的值为iota,每增加一个常量就会使iota自动累加1,所以b和c的值分别为1和2,常量e没有赋值,但它上一个常量d的值为30,所以,常量e的值为30。
3、在const中定义的多个常量,无论里面的常量是否被赋值,iota都会根据常量的数量进行累加计数。
4、值得注意的是,iota只能在关键字const中使用,const外没法使用。
概括来说,iota只限于const中定义的常量进行累加计数,那么问题是,它可能会应用到哪些场景?其实,iota最为典型案例是实现数据存储转换,如下代码所示:
package main
import "fmt"
func main() {
const (
_ = iota // 忽略第一个iota的值 0
KB float64 = 1 << (10 * iota) // 向左移动10位:1 << 10 * 1
MB // 向左移动20位:1 << 10 * 2
GB // 向左移动30位:1 << 10 * 3
TB // 向左移动40位:1 << 10 * 4
)
fmt.Printf("B转KB的进制为:%0.f\n", KB)
fmt.Printf("B转MB的进制为:%0.f\n", MB)
fmt.Printf("B转GB的进制为:%0.f\n", GB)
fmt.Printf("B转TB的进制为:%0.f\n", TB)
}
运行上述代码,结果如图2-3所示。