流程控制
顺序控制
- 程序从上到下逐行地执行,中间没有任何判断和跳转。(例如写脚步)
分支控制
单分支控制
if 条件表达式 {
执行代码块
}
双分支控制
- 双分支只会执行其中的一个分支。
if 条件表达式 {
执行代码块
} else {
执行代码块
}
多分支控制
- 多分支只能有一个执行入口。
if 条件表达式 {
执行代码块
} else if 条件表达式 {
执行代码块
}
...
else {
执行代码块
}
嵌套分支
- 在一个分支结构中又完整的嵌套了另一个完整的分支结构,里面的分支的结构称为内层分支外面的分支结构称为外层分支。
- 嵌套不宜过多,建议控制在3层内。
if 条件表达式 {
if 条件表达式 {
执行代码块
}
}
switch
switch 表达式 {
case 表达式1,表达式2:
执行代码块
case 表达式3:
执行代码块
case 表达式4,表达式5:
执行代码块
default:
执行代码块
}
1) case后是一个表达式(即:常量值、变量、一个有返回值的函数等都可以)
2) case后的各个表达式的值的数据类型,必须和switch 的表达式数据类型一致
3) case后面可以带多个表达式,使用逗号间隔。比如case 表达式1,表达式2…
4) case后面的表达式如果是常量值(字面量),则要求不能重复
5) case后面不需要带break,程序匹配到一个case后就会执行对应的代码块,然后退出switch,如果一个都匹配不到,则执行 default
6) default 语句不是必须的。
7) switch 后也可以不带表达式,类似 if --else 分支来使用。
golang
var n int = 1
switch {
case n > 0:
执行代码块
case n < 0:
执行代码块
case n != 2 && n != 3:
执行代码块
default:
执行代码块
}
8) switch 后也可以直接声明/定义一个变量,分号结束,不推荐。
golang
switch n := 2; {
case n > 0:
执行代码块
case n < 0:
执行代码块
case n != 2 && n != 3:
执行代码块
default:
执行代码块
}
9) switch 穿透-fallthrough ,如果在 case 语句块后增加 fallthrough ,则会继续执行下一个 case,也叫 switch 穿透
golang
var n int = 1
switch {
case n > 0:
执行代码块
fallthrough // 默认只能穿透一层
case n < 0:
执行代码块
fallthrough
case n != 2 && n != 3:
执行代码块
default:
执行代码块
}
10) Type Switch:switch 语句还可以被用于 type-switch 来判断某个 interface 变量中实际指向的变量类型
golang
var x interface{}
var y int = 10
var x = y
switch x.(type) {
case int:
执行代码块
case bool:
执行代码块
case float64:
执行代码块
default:
执行代码块
}
switch 和 if 的比较
- 总结了什么情况下使用 switch ,什么情况下使用 if 1) 如果判断的具体数值不多,而且符合整数、浮点数、字符、字符串这几种类型。建议使用 swtich 语句,简洁高效。 2) 其他情况:对区间判断和结果为 bool 类型的判断,使用 if,if 的使用范围更广。
循环控制
for 循环控制
- 语法格式
for 循环变量初始化; 循环条件; 循环变量迭代 {
循环操作(语句)
}
/*
for i := 0; i < 10; i++ {
fmt.Println(i)
}
*/
1) 对 for 循环来说,有四个要素: 2) 循环变量初始化 3) 循环条件 4) 循环操作(语句) ,有人也叫循环体。 5) 循环变量迭代
-
for 循环执行的顺序说明: 1) 执行循环变量初始化,比如 i := 1 2) 执行循环条件, 比如 i <= 10 3) 如果循环条件为真,就执行循环操作 :比如 fmt.Println(i) 4) 执行循环变量迭代 , 比如 i++ 5) 反复执行 2, 3, 4 步骤,直到 循环条件为 False ,就退出 for 循环。
-
变种写法
//for循环的第二种写法
j := 1 //循环变量初始化
for j <= 10 { //循环条件
fmt.Println("你好,尚硅谷~", j)
j++ //循环变量迭代
}
//for循环的第三种写法, 这种写法通常会配合break使用
k := 1
for { // 这里也等价 for ; ; {
if k <= 10 {
fmt.Println("ok~~", k)
} else {
break //break就是跳出这个for循环
}
k++
}
- for range
// Golang 提供 for-range 的方式,可以方便遍历字符串和数组
//字符串遍历方式-传统方式
// var str string = "hello,world!北京"
// for i := 0; i < len(str); i++ {
// fmt.Printf("%c \n", str[i]) //使用到下标...
// }
// 如果我们的字符串含有中文,那么传统的遍历字符串方式,就是错误,会出现乱码。
//原因是传统的对字符串的遍历是按照字节来遍历,而一个汉字在 utf8 编码是对应 3 个字节
//将str 转成 []rune 切片即可解决
var str string = "hello,world!北京"
str2 := []rune(str) // 就是把 str 转成 []rune
for i := 0; i < len(str2); i++ {
fmt.Printf("%c \n", str2[i]) //使用到下标...
}
//字符串遍历方式-for-range
str = "abc~ok上海"
for index, val := range str {
fmt.Printf("index=%d, val=%c \n", index, val)
}
while 和 do..while 的实现
- Go 语言没有 while 和 do...while 语法,这一点需要同学们注意一下,如果我们需要使用类似其它语言(比如 java / c 的 while 和 do...while ),可以通过 for 循环来实现其使用效果。
while
循环变量初始化
for {
if循环条件表达式{
break //跳出for循环
}
循环操作(语句)
循环娈量迭代
}
1) for 循环是一个无限循环 2) break 语句就是跳出 for 循环
//使用while方式输出10句 "hello,world"
//循环变量初始化
var i int = 1
for {
if i > 10 { //循环条件
break // 跳出for循环,结束for循环
}
fmt.Println("hello,world", i)
i++ //循环变量的迭代
}
fmt.Println("i=", i)
do..while
循环变量初始化
for {
循环操作(语句)
循环娈量迭代
if循环条件表达式{
break //跳出for循环
}
}
1) 上面的循环是先执行,在判断,因此至少执行一次。 2) 当循环条件成立后,就会执行 break, break 就是跳出 for 循环,结束循环.
//使用的do...while实现完成输出10句”hello,ok“
var j int = 1
for {
fmt.Println("hello,ok", j)
j++ //循环变量的迭代
if j > 10 {
break //break 就是跳出for循环
}
}
多重循环控制
1) 将一个循环放在另一个循环体内,就形成了嵌套循环。在外边的 for 称为外层循环在里面的 for 循环称为内层循环。【建议一般使用两层,最多不要超过 3 层】 2) 实质上,嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循环的循环条件为 false 时,才会完全跳出内层循环,才可结束外层的当次循环,开始下一次的循环。 3) 外层循环次数为 m 次,内层为 n 次,则内层循环体实际上需要执行 m*n 次
跳转控制语句-break
- break 语句用于终止某个语句块的执行,用于中断当前 for 循环或跳出 switch 语句
{
......
break
......
}
//我们为了生成一个随机数,还需要个rand设置一个种子.
//time.Now().Unix() : 返回一个从1970:01:01 的0时0分0秒到现在的秒数
//rand.Seed(time.Now().Unix())
//如何随机的生成1-100整数
//n := rand.Intn(100) + 1 // [0 100)
//fmt.Println(n)
//随机生成1-100的一个数,直到生成了99这个数,看看你一共用了几次
//分析思路:
//编写一个无限循环的控制,然后不停的随机生成数,当生成了99时,就退出这个无限循环==》break
var count int = 0
for {
rand.Seed(time.Now().UnixNano())
n := rand.Intn(100) + 1
fmt.Println("n=", n)
count++
if (n == 99) {
break //表示跳出for循环
}
}
fmt.Println("生成 99 一共使用了 ", count)
label
- break 语句出现在多层嵌套的语句块中时,可以通过标签指明要终止的是哪一层语句块
//这里演示一下指定标签的形式来使用 break
lable2:
for i := 0; i < 4; i++ {
//lable1: // 设置一个标签
for j := 0; j < 10; j++ {
if j == 2 {
//break // break 默认会跳出最近的for循环
//break lable1
break lable2 // j=0 j=1
}
fmt.Println("j=", j)
}
}
1) break 默认会跳出最近的 for 循环 2) break 后面可以指定标签,跳出标签对应的 for 循环
跳转控制语句-continue
1) continue 语句用于结束本次循环,继续执行下一次循环。 2) continue 语句出现在多层嵌套的循环语句体中时,可以通过标签指明要跳过的是哪一层循环 , 这个和前面的 break 标签的使用的规则一样.
{
......
continue
......
}
//continue案例
for i := 0; i < 4; i++ {
for j := 0; j < 10; j++ {
if j == 2 {
continue
}
fmt.Println("j=", j)
}
}
//这里演示一下指定标签的形式来使用
here:
for i:=0; i<2; i++ {
for j:=1; j<4; j++ {
if j==2 {
continue here
}
fmt.Println("i=",i,"j=",j)
}
}
跳转控制语句-goto
1) Go 语言的 goto 语句可以无条件地转移到程序中指定的行。 2) goto 语句通常与条件语句配合使用。可用来实现条件转移,跳出循环体等功能。 3) 在 Go 程序设计中一般不主张使用 goto 语句, 以免造成程序流程的混乱,使理解和调试程序都产生困难
{
......
goto label
...... //忽略这段代码
label
......
}
//演示goto的使用
fmt.Println("ok1")
if n > 20 {
goto label1
}
fmt.Println("ok2")
fmt.Println("ok3")
fmt.Println("ok4")
label1:
fmt.Println("ok5")
fmt.Println("ok6")
fmt.Println("ok7")
跳转控制语句-return
1) 如果 return 是在普通的函数,则表示跳出该函数,即不再执行函数中 return 后面代码,也可以理解成终止函数。 2) 如果 return 是在 main 函数,表示终止 main 函数,也就是说终止程序。
func main() {
var n int = 30
//演示return的使用
fmt.Println("ok1")
if n > 20 {
return
}
fmt.Println("ok2")
fmt.Println("ok3")
fmt.Println("ok4")
fmt.Println("ok5")
fmt.Println("ok6")
fmt.Println("ok7")
}