Kodewick
开始学 →
第 2 课,共 24 课目录

变量和零值

第 2 课,共 24 课 · 第 1 部分 · 起步 · 约 15 分钟

程序要记住一些数:商品的价格、买了几件、考试的分数。变量就是一个有名字的格子,里面放一个值。

prog.go
1package main2 3import "fmt"4 5func main() {6	var price int = 257	count := 48	fmt.Println("单价", price, "数量", count)9	fmt.Println("总价", price*count)10}
输出
单价 25 数量 4
总价 100

var price int = 25 的意思是:要一个放整数(int)的格子,名字叫 price,先放进 25。count := 4 是短一点的写法,下面细说。

var 和 :=

var score int 是声明变量:告诉编译器有这么一个变量,它放整数。score = 80 是赋值:往格子里放一个值,旧的值就没了。

:= 把声明和赋值合成一步,类型由右边的值决定:bonus := 10 里的 10 是整数,所以 bonus 是 int。:= 只能在函数里面用,而且只在第一次声明时用;以后再改它,用 =。

prog.go
1package main2 3import "fmt"4 5func main() {6	var score int7	score = 808	fmt.Println(score)9	bonus := 1010	score = score + bonus11	fmt.Println(score)12}
输出
80
90

点单步,看 score 怎么从 0 变成 80,再变成 90。

零值

上面单步时你可能注意到了:var score int 刚声明完,score 里就已经是 0。在 Go 里,声明了却没赋值的变量不是「随便什么值」,而是这种类型的零值:

prog.go
1package main2 3import "fmt"4 5func main() {6	var count int7	var price float648	var name string9	var done bool10	fmt.Println(count, price, done)11	fmt.Println("名字是[" + name + "]")12}
输出
0 0 false
名字是[]

整数和小数的零值是 0,字符串是空字符串 ""(方括号中间什么也没有),bool 是 false。两个字符串用 + 连起来,就是一个更长的字符串。

四种常用的类型

类型放什么例子
int整数30、-5
float64小数1.75、36.6
string文字"上海"
bool真或假true、false

用 := 时不写类型,想知道 Go 定成了什么,可以用 fmt.Printf 的 %T:

prog.go
1package main2 3import "fmt"4 5func main() {6	age := 307	height := 1.758	city := "上海"9	member := true10	fmt.Printf("%T\n", age)11	fmt.Printf("%T\n", height)12	fmt.Printf("%T\n", city)13	fmt.Printf("%T\n", member)14}
输出
int
float64
string
bool

Printf 按格式显示:引号里的 %T 换成后面那个值的类型。Printf 不会自己换行,所以末尾写 \n。写 30 是 int,写 1.75 是 float64。

一次声明几个

几个变量可以写在一行里,:= 和 = 都行。low, high = high, low 一步就把两个值换过来:

prog.go
1package main2 3import "fmt"4 5func main() {6	var width, height int = 3, 47	fmt.Println("面积", width*height)8	low, high := 18, 269	fmt.Println("温度", low, "到", high)10	low, high = high, low11	fmt.Println("换过以后", low, high)12}
输出
面积 12
温度 18 到 26
换过以后 26 18

常量

有的值定下来就不会变:一周 7 天、税率 10%。用 const 声明常量,可以写在函数外面,整个程序都能用:

prog.go
1package main2 3import "fmt"4 5const taxRate = 0.16 7func main() {8	const days = 79	price := 200.010	fmt.Println("税", price*taxRate)11	fmt.Println("两周", days*2, "天")12}
输出
税 20
两周 14 天

常量不能再赋值:在 main 里加一行 days = 8,编译器就会报错。写 200.0 而不是 200,price 才是 float64。

类型不能混着算

Go 不会自己把 int 变成 float64。整数和小数直接相乘,编译不过:

prog.go
1package main2 3import "fmt"4 5func main() {6	count := 37	price := 2.58	total := count * price9	fmt.Println(total)10}
输出
# command-line-arguments
./prog.go:8:11: invalid operation: count * price (mismatched types int and float64)

发生了什么: 两边的类型不一样(int 和 float64),Go 不会自动换:用 float64(x) 或 int(x) 先转成同一种。

报错说:count * price 这个运算不行,两边的类型对不上,一个是 int,一个是 float64。要自己转换:float64(count) 得到同样大小的 float64,int(price) 得到 int,小数部分直接去掉(不是四舍五入):

prog.go
1package main2 3import "fmt"4 5func main() {6	count := 37	price := 2.58	total := float64(count) * price9	fmt.Println(total)10	fmt.Println(int(price))11}
输出
7.5
2

还有一点:两个整数相除,结果还是整数,小数部分去掉。% 是余数:17 % 5 是 2。

先猜一猜

这段程序显示什么?

1package main2 3import "fmt"4 5func main() {6	total := 177	people := 28	fmt.Println(total / people)9}

没用到的变量

第 1 课说过:没用到的包是编译错误。没用到的变量也一样:

prog.go
1package main2 3import "fmt"4 5func main() {6	price := 257	discount := 58	fmt.Println(price)9}
输出
# command-line-arguments
./prog.go:7:2: declared and not used: discount

发生了什么: 变量 discount 声明了却没有用到。Go 不允许这样:用上它,或者删掉它(不想要的值可以给 _)。

./prog.go:7:2 是第 7 行第 2 个字符:discount 声明了,后面却一次也没用。只赋值不算「用」,要读它才算。删掉这一行,或者把它用上(比如显示 price - discount),就能运行了。

练一练

写好代码,点检查。提示随便看,实在想不出来再看答案。

练习 1

修好它:整数乘小数

这段程序编译不过。改好它,让它显示两件商品的总价:总价 50 和 总价 16。

要显示
总价 50
总价 16
exercise1.go
1package main2 3import "fmt"4 5func main() {6	price := 12.57	count := 48	fmt.Println("总价", price*count)9	price = 3.210	count = 511	fmt.Println("总价", price*count)12}
输出
点「运行」或按 Ctrl+Enter
练习 2

平均分要带小数

程序算两个同学四次考试的平均分,可是小数部分不见了。改好它,显示 平均分 83.25 和 平均分 78。

要显示
平均分 83.25
平均分 78
exercise2.go
1package main2 3import "fmt"4 5func main() {6	a, b, c, d := 90, 85, 78, 807	fmt.Println("平均分", (a+b+c+d)/4)8	a, b, c, d = 70, 81, 95, 669	fmt.Println("平均分", (a+b+c+d)/4)10}
输出
点「运行」或按 Ctrl+Enter
练习 3

分组

一些人每几个人分一组。用 / 和 % 算出能分几组、剩几个人,显示 5 组 剩 3 人(23 人,每组 4 人)和 5 组 剩 0 人(30 人,每组 6 人)。

要显示
5 组 剩 3 人
5 组 剩 0 人
exercise3.go
1package main2 3import "fmt"4 5func main() {6	people, size := 23, 47	fmt.Println(people, size)8	people, size = 30, 69	fmt.Println(people, size)10}
输出
点「运行」或按 Ctrl+Enter

这一课学会了

  • var x int 声明变量;x := 值 声明并赋值,类型由值决定;以后改它用 =。
  • 没赋值的变量是零值:数是 0,字符串是 "",bool 是 false。
  • 常用的类型:int、float64、string、bool;fmt.Printf("%T\n", x) 显示类型。
  • const 声明常量,不能再改。
  • int 和 float64 不能直接一起算,要用 float64(n)、int(x) 转换;整数相除去掉小数,% 是余数。
  • 声明了却没用到的变量是编译错误。
这一课学完了吗?点一下标记。进度存在这个浏览器里,随时可以撤销。