12.流程控制#
通常我们需要代码在满足一定条件时候进行执行,或者需要重复执行代码,此时条件语句(if-else if -else)或者选择语句(swicth case)及循环语句(for)
!!! note
老婆给老公打电话,下班顺路买十个包子,如果看到买西瓜的,买一个。当晚老公拿着一个包子回家。老婆问道:你怎么只买了一个包子?老公回答:因为我看到卖西瓜的了。
if else#
老婆的想法,如果看到买西瓜的,买一个西瓜,代码:
package main
import "fmt"
func main(){
fmt.Print("老婆的想法:")
fmt.Println("买10个包子")
var yes string
fmt.Print("是否有卖西瓜的?")
fmt.Scan(&yes)
if yes == "Y"|| yes == "y" {
fmt.Println("买一个西瓜")
}
}
看到卖西瓜的,买一个西瓜,运行:
[root@marksugar /opt/Golang]# go run if1.go
老婆的想法:买10个包子
是否看到卖西瓜的?y
买一个西瓜
如果没看到就买10个包子:
[root@marksugar /opt/Golang]# go run if1.go
老婆的想法:买10个包子
是否看到卖西瓜的?n
老公的想法是,如果看到买西瓜的,就买一个包子,否则就买10个包子。代码如下:
package main
import "fmt"
func main(){
fmt.Print("老婆的想法:")
fmt.Println("买10个包子")
var yes string
fmt.Print("是否看到卖西瓜的?")
fmt.Scan(&yes)
if yes == "Y"|| yes == "y" {
fmt.Println("买一个西瓜")
}
fmt.Print("老公的想法:")
if yes == "y"|| yes == "Y" {
fmt.Println("买一个包子")
}else {
fmt.Println("买10个包子")
}
}
如果看到了买西瓜的,买一个包子:
[root@marksugar /opt/Golang]# go run if1.go
老婆的想法:买10个包子
是否看到卖西瓜的?y
买一个西瓜
老公的想法:买一个包子
如果没看到,就买10个包子:
[root@marksugar /opt/Golang]# go run if1.go
老婆的想法:买10个包子
是否看到卖西瓜的?n
老公的想法:买10个包子
if else if#
如果输入大于等于90就打印A,大于等于80打印B,大于等于70打印C,大于等于60打印D,小于60就打印D-不及格。如下
var score int
fmt.Print("请输入成绩:")
fmt.Scan(&score)
if score >= 90 {
fmt.Println("A")
} else if score >= 80 {
fmt.Println("B")
} else if score >= 70 {
fmt.Println("C")
} else if score >= 60 {
fmt.Println("D")
} else {
fmt.Println("D-,不及格")
}
运行
[root@marksugar /opt/Golang]# go run if1.go
请输入成绩:70
C
switch#
switch和if很相似。这里分为switch单值和表达式
老婆的想法:
package main
import "fmt"
func main(){
var yes string
fmt.Print("是否看到卖西瓜的?")
fmt.Scan(&yes)
fmt.Print("老婆的想法:")
fmt.Println("买10个包子")
switch yes {
case "y":
fmt.Println("买一个西瓜y")
case "Y":
fmt.Println("买一个西瓜Y")
}
}
输入小y:
[root@marksugar /opt/Golang]# go run switch.go
是否看到卖西瓜的?y
老婆的想法:买10个包子
买一个西瓜y
输入大Y:
[root@marksugar /opt/Golang]# go run switch.go
是否看到卖西瓜的?Y
老婆的想法:买10个包子
买一个西瓜Y
输入n:
[root@marksugar /opt/Golang]# go run switch.go
是否看到卖西瓜的?n
老婆的想法:买10个包子
!!! note
这里的switch可以写成一条
case "y","Y":
fmt.Println("买一个西瓜")
}
老公的想法
switch default#
package main
import "fmt"
func main(){
var yes string
fmt.Print("是否看到卖西瓜的?")
fmt.Scan(&yes)
fmt.Print("老公的想法:")
fmt.Println("买10个包子")
switch yes {
case "y","Y":
fmt.Println("买一个包子")
default:
fmt.Println("买十个包子")
}
}
看到卖西瓜的:
[root@marksugar /opt/Golang]# go run switch.go
是否看到卖西瓜的?y
老公的想法:买10个包子
买一个包子
没看到买西瓜的:
[root@marksugar /opt/Golang]# go run switch.go
是否看到卖西瓜的?n
老公的想法:买10个包子
买十个包子
在用switch的方式修改,如果输入大于等于90就打印A,大于等于80打印B,大于等于70打印C,大于等于60打印D,小于60就打印D-不及格。如下:
var score int
fmt.Print("请输入成绩:")
fmt.Scan(&score)
switch {
case score >= 90:
fmt.Println("A")
case score >= 80:
fmt.Println("B")
case score >= 70:
fmt.Println("C")
case score >= 60:
fmt.Println("D")
default:
fmt.Println("D-,不及格")
}
运行
[root@marksugar /opt/Golang]# go run switch.go
请输入成绩:90
A
[root@marksugar /opt/Golang]# go run switch.go
请输入成绩:80
B
[root@marksugar /opt/Golang]# go run switch.go
请输入成绩:70
C
[root@marksugar /opt/Golang]# go run switch.go
请输入成绩:60
D
[root@marksugar /opt/Golang]# go run switch.go
请输入成绩:50
D-,不及格
for循环#
重复做一件事情。一般而言,我们会设置一个索引,记录已经加到了多少,并记录结果。那么,至少定义两个变量。
先看下不用for循环的方式。
result := 0
此时定义一个result 0,如果要加到100次,我们需要相加100次
result += 1
result += 2
...
result += 100
如果现在使用for循环,for循环有三个子语句分别是初始化子语句,条件子语句,后值子语句。
for i := 1; i <= 100; i++ {}
如上。
- 初始化子语句,i := 1
初始化一个值
- 条件子语句: i < 100
当满足某个条件时候执行循环
- 后值子语句: i++
函数体执行完成后执行的代码。
整体的意思就是,i等于1,且i小于等于100,就开始执行i++语句快(反义则是i大于100就不执行)。如下:
package main
import "fmt"
func main(){
result := 0
for i:=1;i<=100;i++{
result += i
fmt.Println(i)
}
fmt.Println(result)
}
运行
[root@marksugar /opt/Golang]# go run for.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
5050
这里打印了i,i的确加了100次,结果是5050
!!! note
在go中只有for循环,没有其他的循环,如while等
for一个子语句#
除了上述这种,还有其他的方式实现。比如一个子语句:
result = 0
i := 1
for i<= 100{
result += i
i++
}
package main
import "fmt"
func main(){
result := 0
i := 1
for i<= 100{
result += i
i++
}
fmt.Println(result)
}
运行
[root@marksugar /opt/Golang]# go run for2.go
5050
for死循环#
在go中,死循环使用for即可
package main
import "fmt"
func main(){
i :=0
for {
fmt.Println(i)
i++
}
}
除此之外,for循环还有遍历的for range
for range#
for range在go中非常常用,可以遍历字符串,数组,切片,映射,管道。
一般而言,for range遍历,有一个索引和一个值,这与需要变量的对象有关。 简单的认为一个是索引index,和一个value即可
desc := "我是marksugar"
for index,value := range desc {
fmt.Printf("%d %T %q\n",index,value,value)
}
运行
[root@marksugar /opt/Golang]# go run for3.go
0 int32 '我'
3 int32 '是'
6 int32 'm'
7 int32 'a'
8 int32 'r'
9 int32 'k'
10 int32 's'
11 int32 'u'
12 int32 'g'
13 int32 'a'
14 int32 'r'
- 在for range中,如果不需要index或者value,可以使用_(下划线)不接收
desc := "我是marksugar" for _,value := range desc {} 注意:这里的空白标识符是go内置,我们只能对它进行赋值
比如下面这段代码:
var value int _,value = 1,2 fmt.Println(value) 这里的输出是2。这里值得注意的是,因为空白标识符是内置的,不能使用:=(冒号)定义 。如果一定要使用:=赋值,在简短声明中,至少需要有一个是新定义的。那么需要如下定义:
package main import "fmt" func main(){ var value int _,value = 1,4 fmt.Println(value) } 运行:
[root@linuxea-marksugar /opt/Golang/work2]# go run biaoshifu.go 4 如果这里使用简短声明就会报错的
# command-line-arguments ./biaoshifu.go:5:10: no new variables on left side of := ./biaoshifu.go:7:1: syntax error: unexpected EOF, expecting } 如果我们要使用简短声明就需要一个新的变量,如下
package main import "fmt" func main(){ var value int _,value,newvalue := 1,4,5 fmt.Println(value,newvalue) } 运行
[root@linuxea-marksugar /opt/Golang/work2]# go run biaoshifu.go 4 5
brack和continue#
brack和continue 只能在循环中使用
我们先定义,i:=0
,并且i<5
,正常情况下,将会打印0~4
package main
import "fmt"
func main(){
for i :=0;i<5;i++{
fmt.Println(i)
}
}
运行
[root@marksugar /opt/Golang]# go run brack1.go
0
1
2
3
4
为了能够加以区分,我们在这段代码上分别加上break和continue
如果i等于3就执行continue,break
[root@marksugar /opt/Golang]# cat brack.go
package main
import "fmt"
func main(){
fmt.Println("continue:")
for i :=0;i<5;i++{
if i == 3 {
continue
}
fmt.Println(i)
}
fmt.Println("break:")
for i :=0;i<5; i++{
if i ==3 {
break
}
fmt.Println(i)
}
}
运行:
[root@marksugar /opt/Golang]# go run brack.go
continue:
0
1
2
4
break:
0
1
2
如上所示:
在continue中,当i等于3就跳过继续执行子语句之后的条件,直到满足条件小于5
在break中,当i等于3就停止执行后面的子语句。
- 总结
continue执行到就会跳过本次执行,继续循环
break执行到后就会跳出循环
13.goto#
与brack和continue不同,goto只有在C和go中才有。
goto作为跳转,需要定义一个label标签。这个标签决定跳转到哪里。并且break也可以配合标签使用,见示例3
goto示例1#
但输入内容为c/u/r/d
,打印create,update,read,delete,如果输入都不是,就重新执行循环。也就是说只有输入c/u/r/d
程序才会结束。
代码如下:
package main
import "fmt"
func main(){
START:
fmt.Print("input:(c/u/r/d):")
var in string
fmt.Scan(&in)
for {
if in == "c"{
fmt.Println("create")
break
}else if in == "u" {
fmt.Println("update")
break
}else if in == "r" {
fmt.Println("read")
break
}else if in == "d" {
fmt.Println("delete")
break
}else if in != "c" && in != "u" && in != "r" && in != "d" {
goto START
}
}
}
跳出在 这里使用不等于!=
,如果输入的不等于就跳转到标签START。如果输入c/u/r/d
任意一个即可。
运行:
[root@marksugar /opt/Golang]# go run goto.go
input:(c/u/r/d):s
input:(c/u/r/d):.
input:(c/u/r/d):1
input:(c/u/r/d):2
input:(c/u/r/d):3
input:(c/u/r/d):a
input:(c/u/r/d):c
create
goto示例2#
从1加到100的和,不用for循环
如果i小于100,就result就等于i,进行i++,跳转到START判断继续循环。直到大于100,就跳转到FOREND
代码如下:
package main
import "fmt"
func main(){
result := 0
i := 1
START:
for i>100 {
fmt.Println(i)
goto FOREND
}
result += i
i++
goto START
FOREND:
fmt.Println(result)
}
运行
[root@marksugar /opt/Golang]# go run goto2.go
101
5050
goto示例3#
定义嵌套循环,分别i和j,i和j相乘,如果等于9就结束程序。使用break 和BREAKEND标签。代码如下:
package main
import "fmt"
func main(){
BREAKEND:
for i :=0;i<5;i++{
for j :=0; j<5;j++{
if i*j == 9 {
break BREAKEND
}
fmt.Println(i,j,i*j)
}
}
}
!!! note break的标签需要在循环层级之上,不能写在下面
运行:
[root@marksugar /opt/Golang]# go run brack2.go
0 0 0
0 1 0
0 2 0
0 3 0
0 4 0
1 0 0
1 1 1
1 2 2
1 3 3
1 4 4
2 0 0
2 1 2
2 2 4
2 3 6
2 4 8
3 0 0
3 1 3
3 2 6
练习题#
-
打印乘法口诀 for + if + fmt.Println + fmt.Printf
-
猜数字游戏 for if continue/break a. 生成一个[0, 100)随机数 b. 让用户最多猜 5次(从命令行输入一个整数) 猜的太大 => 提示太大了,你还有N此猜测机会 猜的太小 => 提示太小了,你还有N此猜测机会 猜中了 => 猜中了
5次都没猜中 => 退出,并提示太笨了
挑战: 当5此都没有猜中:提示太笨了,重新开始猜数游戏(重新生成随机数,重新开始5次计数)
练习题1示例#
成法表,从1开始相乘,1*1,1*2,1*3,等等,这样使用for循环可以实现,如下:
for i :=1;i<=line;i++ {
fmt.Printf("%d * %d = %-2d ",i,line,i*line)
}
1x1
1x2 2x2
1x3 2x3 3x3
1x4 2x4 3x4 4x4
这里而后还需要进行一次循环,9以内要进行相乘。最终如下:
package main
import "fmt"
func main(){
for line :=1;line <=9;line++ {
for i :=1;i<=line;i++ {
fmt.Print(i,"x",line,"=",i*line,"\t")
}
fmt.Println()
}
}
运行
[root@linuxea-marksugar /opt/Golang]# go run 99xfb2.go
1x1=1
1x2=2 2x2=4
1x3=3 2x3=6 3x3=9
1x4=4 2x4=8 3x4=12 4x4=16
1x5=5 2x5=10 3x5=15 4x5=20 5x5=25
1x6=6 2x6=12 3x6=18 4x6=24 5x6=30 6x6=36
1x7=7 2x7=14 3x7=21 4x7=28 5x7=35 6x7=42 7x7=49
1x8=8 2x8=16 3x8=24 4x8=32 5x8=40 6x8=48 7x8=56 8x8=64
1x9=9 2x9=18 3x9=27 4x9=36 5x9=45 6x9=54 7x9=63 8x9=72 9x9=81
或者这样,使用Printf,这里还是用了负号,左对齐-2d
package main
import "fmt"
func main(){
for line :=1;line <=9;line++ {
for i :=1;i<=line;i++ {
fmt.Printf("%d * %d = %-2d ",i,line,i*line)
}
fmt.Println()
}
}
运行:
[root@marksugar /opt/Golang]# go run 99xfb.go
1 * 1 = 1
1 * 2 = 2 2 * 2 = 4
1 * 3 = 3 2 * 3 = 6 3 * 3 = 9
1 * 4 = 4 2 * 4 = 8 3 * 4 = 12 4 * 4 = 16
1 * 5 = 5 2 * 5 = 10 3 * 5 = 15 4 * 5 = 20 5 * 5 = 25
1 * 6 = 6 2 * 6 = 12 3 * 6 = 18 4 * 6 = 24 5 * 6 = 30 6 * 6 = 36
1 * 7 = 7 2 * 7 = 14 3 * 7 = 21 4 * 7 = 28 5 * 7 = 35 6 * 7 = 42 7 * 7 = 49
1 * 8 = 8 2 * 8 = 16 3 * 8 = 24 4 * 8 = 32 5 * 8 = 40 6 * 8 = 48 7 * 8 = 56 8 * 8 = 64
1 * 9 = 9 2 * 9 = 18 3 * 9 = 27 4 * 9 = 36 5 * 9 = 45 6 * 9 = 54 7 * 9 = 63 8 * 9 = 72 9 * 9 = 81
2.猜数字游戏 for if continue/break a. 生成一个[0, 100)随机数 b. 让用户最多猜 5次(从命令行输入一个整数) 猜的太大 => 提示太大了,你还有N此猜测机会 猜的太小 => 提示太小了,你还有N此猜测机会 猜中了 => 猜中了
5次都没猜中 => 退出,并提示太笨了
挑战: 当5此都没有猜中:提示太笨了,重新开始猜数游戏(重新生成随机数,重新开始5次计数)
!!! note 需要一个随机数的种子
会用到time和math/rand模块
package main
import (
"fmt"
"math/rand"
"time"
)
func main(){
rand.Seed(time.Now().Unix())
fmt.Println(rand.Int())
}
这样我们会拿到一串随机数
[root@marksugar /opt/Golang]# go run work11.go
4539660804304182971
[root@marksugar /opt/Golang]# go run work11.go
125010350273079313
[root@marksugar /opt/Golang]# go run work11.go
5357909466568961262
而后使用% 100
对0~100取余
package main
import (
"fmt"
"math/rand"
"time"
)
func main(){
rand.Seed(time.Now().Unix())
fmt.Println(rand.Int() % 100)
}
运行
[root@marksugar /opt/Golang]# go run work11.go
90
[root@marksugar /opt/Golang]# go run work11.go
15
[root@marksugar /opt/Golang]# go run work11.go
15
[root@marksugar /opt/Golang]# go run work11.go
89
!!! note 也可以使用Intn(100)也可以取余
rand.Seed(time.Now().Unix())
fmt.Println(rand.Intn(100))
[root@marksugar /opt/Golang]# go run work11.go
72
[root@marksugar /opt/Golang]# go run work11.go
2
[root@marksugar /opt/Golang]# go run work11.go
15
练习题2示例#
-
定义了一个dadata函数,使用系统时间作为随机种子,获取100内的随机数,这样每次都会重新获取。
-
使用for嵌套了这个dadata函数,在执行三次失败后,会重新执行这个函数获取0~100的随机数。
-
如果输入信息满足条件,使用goto 跳出循环。
代码如下:
package main
import (
"fmt"
"math/rand"
"strconv"
"time"
)
func dadata(sjs int) int{
rand.Seed(time.Now().UnixNano()) // 系统时间为随机种子
return rand.Intn(sjs)
}
func main(){
for {
sjs := dadata(100)
fmt.Println(sjs)
num := 3
var dA1 string
for i:=0;i<=3;i++{
rnum := num - i
fmt.Print("开始猜数字游戏,请输入:")
fmt.Scanf("%v",&dA1)
dA1,err := strconv.ParseInt(dA1,10,0) // 判断输入的是整数
if err != nil {
fmt.Println("你输入的不是数字",err)
break
}else if int(dA1) == sjs {
fmt.Printf("恭喜你猜对了数字是%v!", sjs)
goto ENDD
} else if int(dA1) > sjs {
fmt.Printf("猜大了,你还可以猜测%v次\n",rnum)
} else if int(dA1) < sjs {
fmt.Printf("猜小了,你还可以猜测%v次\n",rnum)
}
}
}
ENDD:
}
运行
[root@marksugar /opt/Golang]# go run work1.go
5
开始猜数字游戏,请输入:6
猜大了,你还可以猜测3次
开始猜数字游戏,请输入:9
猜大了,你还可以猜测2次
开始猜数字游戏,请输入:8
猜大了,你还可以猜测1次
开始猜数字游戏,请输入:2
猜小了,你还可以猜测0次
39
开始猜数字游戏,请输入:39
恭喜你猜对了数字是39!
当然,这里也可以使用bool类型来判断
package main
import (
"fmt"
"math/rand"
"strconv"
"time"
)
func dadata(sjs int) int{
rand.Seed(time.Now().UnixNano()) // 系统时间为随机种子
return rand.Intn(sjs)
}
func main(){
for {
sjs := dadata(100)
fmt.Println(sjs)
num := 3
var okk bool
var dA1 string
for i:=0;i<=3;i++{
rnum := num - i
fmt.Print("开始猜数字游戏,请输入:")
fmt.Scanf("%v",&dA1)
dA1,err := strconv.ParseInt(dA1,10,0) // 判断输入的是整数
if err != nil {
fmt.Println("你输入的不是数字",err)
break
}else if int(dA1) == sjs {
okk = true
fmt.Printf("恭喜你猜对了数字是%v!", sjs)
goto ENDD
} else if int(dA1) > sjs {
fmt.Printf("猜大了,你还可以猜测%v次\n",rnum)
} else {
fmt.Printf("猜小了,你还可以猜测%v次\n",rnum)
}
}
if !okk {
fmt.Println("游戏结束!")
}
}
ENDD:
}
运行
[root@linuxea-marksugar /opt/Golang]# go run work3.go
69
开始猜数字游戏,请输入:321
猜大了,你还可以猜测3次
开始猜数字游戏,请输入:321
猜大了,你还可以猜测2次
开始猜数字游戏,请输入:321
猜大了,你还可以猜测1次
开始猜数字游戏,请输入:312
猜大了,你还可以猜测0次
游戏结束!
5
开始猜数字游戏,请输入:321
猜大了,你还可以猜测3次
开始猜数字游戏,请输入:312
猜大了,你还可以猜测2次
开始猜数字游戏,请输入:321
猜大了,你还可以猜测1次
开始猜数字游戏,请输入:312
猜大了,你还可以猜测0次
游戏结束!
62
开始猜数字游戏,请输入:62
恭喜你猜对了数字是62!