变量和零值
程序要记住一些数:商品的价格、买了几件、考试的分数。变量就是一个有名字的格子,里面放一个值。
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。:= 只能在函数里面用,而且只在第一次声明时用;以后再改它,用 =。
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 里,声明了却没赋值的变量不是「随便什么值」,而是这种类型的零值:
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:
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 一步就把两个值换过来:
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 声明常量,可以写在函数外面,整个程序都能用:
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。整数和小数直接相乘,编译不过:
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,小数部分直接去掉(不是四舍五入):
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}
total 和 people 都是 int,整数除以整数还是整数,8.5 的小数部分直接去掉,得 8。想要 8.5,写 float64(total) / float64(people)。
没用到的变量
第 1 课说过:没用到的包是编译错误。没用到的变量也一样:
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),就能运行了。
练一练
写好代码,点检查。提示随便看,实在想不出来再看答案。
修好它:整数乘小数
✓这段程序编译不过。改好它,让它显示两件商品的总价:总价 50 和 总价 16。
总价 50 总价 16
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}
平均分要带小数
✓程序算两个同学四次考试的平均分,可是小数部分不见了。改好它,显示 平均分 83.25 和 平均分 78。
平均分 83.25 平均分 78
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}
分组
✓一些人每几个人分一组。用 / 和 % 算出能分几组、剩几个人,显示 5 组 剩 3 人(23 人,每组 4 人)和 5 组 剩 0 人(30 人,每组 6 人)。
5 组 剩 3 人 5 组 剩 0 人
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}
这一课学会了
var x int声明变量;x := 值声明并赋值,类型由值决定;以后改它用=。- 没赋值的变量是零值:数是 0,字符串是
"",bool是false。 - 常用的类型:
int、float64、string、bool;fmt.Printf("%T\n", x)显示类型。 const声明常量,不能再改。int和float64不能直接一起算,要用float64(n)、int(x)转换;整数相除去掉小数,%是余数。- 声明了却没用到的变量是编译错误。