if 和 switch
到现在为止,程序里的每一行都会运行。可是很多时候要先看情况:分数够了才显示「及格」,下雨了才带伞。if 就是做这个的:
1package main2 3import "fmt"4 5func main() {6 score := 727 if score >= 60 {8 fmt.Println("及格")9 }10 fmt.Println("分数", score)11}
及格 分数 72
score >= 60 是条件,结果是 true 或 false。是 true,就运行花括号里的代码块;是 false,就跳过它。把 72 改成 55 再运行一次。
比较用的符号:
| 写法 | 意思 |
|---|---|
a == b | 等于(两个等号) |
a != b | 不等于 |
a < b、a <= b | 小于、小于等于 |
a > b、a >= b | 大于、大于等于 |
else 和 else if
else 是「不然的话」。中间还可以接几个 else if。Go 从上往下一个个看条件,运行第一个成立的那一块,后面的都不看了:
1package main2 3import "fmt"4 5func main() {6 temp := 187 if temp >= 26 {8 fmt.Println("热,开空调")9 } else if temp >= 16 {10 fmt.Println("正舒服")11 } else {12 fmt.Println("冷,穿外套")13 }14}
正舒服
点单步,看它判断了哪几个条件。注意 } else { 要写在同一行:} 后面换行再写 else,Go 会在 } 后面加上分号,编译就不过了。
这段程序显示什么?
1package main2 3import "fmt"4 5func main() {6 score := 957 if score >= 60 {8 fmt.Println("及格")9 } else if score >= 90 {10 fmt.Println("优秀")11 }12}
95 让第一个条件 score >= 60 成立,显示「及格」,后面的 else if 就不再看了。条件要从严到宽排:先问 >= 90,再问 >= 60。
不要括号,要花括号
条件外面不用加括号:写 if score >= 60,不写 if (score >= 60)(加了也能运行,但 gofmt 会把它去掉)。花括号却一定要写,哪怕里面只有一行:
1package main2 3import "fmt"4 5func main() {6 price := 1207 if price > 1008 fmt.Println("满 100 了")9}
# command-line-arguments
./prog.go:8:29: syntax error: unexpected newline, expected { after if clause发生了什么: 语法错误:这一行好像没写完(少了括号、逗号,或者 { 要和 if / for / func 写在同一行)。
报错指向第 8 行的末尾:编译器一直读到这里,也没看到 if 后面该有的 {。在条件后面加上 {,在 fmt.Println 那一行下面加上 },就好了。
并且、或者、不
几个条件可以连起来:&& 是「并且」,两边都成立才成立;|| 是「或者」,有一边成立就成立;! 是「不」,把 true 和 false 反过来。
1package main2 3import "fmt"4 5func main() {6 temp := 227 raining := false8 if temp >= 18 && !raining {9 fmt.Println("去公园")10 }11 if temp < 5 || raining {12 fmt.Println("待在家里")13 }14}
去公园
raining 是 bool,可以直接当条件,不用写 raining == true。把 raining 改成 true 再试试。
if 带初始化
if 后面可以先写一个短语句,用分号隔开,再写条件。在这里声明的变量,只在这个 if 和它的 else 里能用:
1package main2 3import "fmt"4 5func main() {6 price, count := 35, 37 if total := price * count; total >= 100 {8 fmt.Println("总价", total, "免运费")9 } else {10 fmt.Println("总价", total, "运费 10 元")11 }12}
总价 105 免运费
出了这个 if,total 就没有了。在最后加一行 fmt.Println(total),编译器会说 undefined: total。这样临时的变量不会到处都是。
switch
一个值要和好几个值比的时候,switch 比一长串 else if 清楚。一个 case 可以写几个值,用逗号隔开;都对不上就走 default:
1package main2 3import "fmt"4 5func main() {6 day := 67 switch day {8 case 1, 2, 3, 4, 5:9 fmt.Println("工作日")10 case 6, 7:11 fmt.Println("周末")12 default:13 fmt.Println("没有这一天")14 }15}
周末
和 C、Java 不一样,Go 的 case 做完就离开 switch,不用写 break。
这段程序显示几行?
1package main2 3import "fmt"4 5func main() {6 size := "M"7 switch size {8 case "S":9 fmt.Println("小号")10 case "M":11 fmt.Println("中号")12 case "L":13 fmt.Println("大号")14 }15}
size 是 "M",只运行 case "M" 那一块,显示「中号」,然后就离开 switch。Go 不会接着往下走到 case "L"。
不带条件的 switch
switch 后面什么都不写,每个 case 就是一个条件。和 if 一样,从上往下运行第一个成立的:
1package main2 3import "fmt"4 5func main() {6 score := 857 switch {8 case score >= 90:9 fmt.Println("A")10 case score >= 80:11 fmt.Println("B")12 case score >= 60:13 fmt.Println("C")14 default:15 fmt.Println("D")16 }17}
B
这是长长的 if、else if 链的另一种写法,读起来像一张表。真想接着做下一个 case,可以在 case 的最后写 fallthrough,不过很少用到。
练一练
写好代码,点检查。提示随便看,实在想不出来再看答案。
及格还是补考
✓两个分数,60 分以上(含 60)先显示分数,再显示 及格;不到 60 先显示分数,再显示 补考。要显示 72 及格 和 55 补考。
72 及格 55 补考
1package main2 3import "fmt"4 5func main() {6 score := 727 fmt.Println(score)8 score = 559 fmt.Println(score)10}
修好它:换了行的 else
✓这段程序编译不过。改好它,让它显示 开空调 和 开窗。
开空调 开窗
1package main2 3import "fmt"4 5func main() {6 temp := 287 if temp > 25 {8 fmt.Println("开空调")9 }10 else {11 fmt.Println("开窗")12 }13 temp = 1814 if temp > 25 {15 fmt.Println("开空调")16 }17 else {18 fmt.Println("开窗")19 }20}
按重量算快递费
✓快递费:不超过 1 公斤 8 元,不超过 5 公斤 15 元,再重 30 元。用不带条件的 switch 算出 fee,显示 3 公斤 15 元 和 12 公斤 30 元。
3 公斤 15 元 12 公斤 30 元
1package main2 3import "fmt"4 5func main() {6 weight := 37 fee := 08 fmt.Println(weight, "公斤", fee, "元")9 weight = 1210 fmt.Println(weight, "公斤", fee, "元")11}
这一课学会了
if 条件 { … }:条件成立才运行代码块;else if、else接在后面,只运行第一个成立的那块。- 条件不加括号,花括号一定要写,
} else {写在同一行。 &&并且、||或者、!不。if x := …; 条件 { … }里声明的变量只在这个if和else里有。switch的case做完就离开,不用break;一个case可以有几个值,都不对走default。- 不带条件的
switch每个case是一个条件,代替长长的if链;fallthrough接着做下一个case。