
流程控制
1.选择结构语句
- if语句
在编程中实现选择判断结构就是用 if
if结构语法if 条件判断 { // 代码语句 }条件判断如果为真(true),那么就执行if大括号中的语句。
条件判断如果为假(false),那么就执行else大括号中的语句。
if代码块或else代码块,必须有一块被执行。
- if判断布尔变量
age, ok := ages["bob"] if !ok { "bob不是字典中的建,age == 0" }合并为一条语句
if age, ok := ages["bob"]; !ok { "bob不是字典中的建,age == 0" }
- if else if结构语法
从上到下依次判断条件,如果结果为真,就执行 { } 内的代码
if 条件判断1 { // 代码语句1 } else if 条件判断2 { // 代码语句2 } else if 条件判断3 { // 代码语句3 } else { // 代码语句4 }//通过键盘获取数据 存放变量中 fmt.Scan(&score) //阻塞式请求package main import "fmt" func main() { //if 表达式 {代码} 如果表达式为真 执行{}的代码 //if 表达式 {代码1} else{代码2} 如果表达式为真 执行代码1内容 如果为假 执行代码2 //if 表达式1 {代码1} else if表达式2{代码2}else{代码3} 依次判断表达式 满足条件执行 score := 0 //通过键盘获取数据 存放变量中 fmt.Scan(&score) //阻塞式请求 if score > 700 { fmt.Println("我要上清华") } else if score > 680 { fmt.Println("我要上北大") } else { fmt.Println("我要上蓝翔") } }
- switch
switch 变量或者表达式的值 { case 值1: // 代码语句1 case 值2: // 代码语句2 case 值3: // 代码语句3 default: // 代码语句4 }执行流程:
程序执行到switch处,首先将变量或者表达式的值计算出来,然后拿着这个值依次跟每个case后面所带的值进行匹配,一旦匹配成功,则执行该case所带的代码,执行完成后,跳出switch-case结构。如果,跟每个case所带的值都不匹配。就看当前这个switch-case结构中是否存在default,如果有default,则执行default中的语句,如果没有default,则该switch-case结构什么都不做。
注意:
某个case 后面跟着的代码执行完毕后,不会再执行后面的case,而是跳出整个switch结构, 相当于每个case后面都跟着break(终止)。
但是如果想执行完成某个case后,强制执行后面的case,可以使用fallthrough。switch 表达式{case 值1: 代码1 case 值2: 代码2} 哪个分支满足条件指向哪条
package main import "fmt" func main() { //switch 表达式{case 值1: 代码1 case 值2: 代码2} 哪个分支满足条件指向哪条 //输入月份 计算天数 day := 0 m := 0 fmt.Scan(&m) switch m { //如果有多个值 执行相同的代码,可以使用逗号分隔 case 1, 3, 5, 7, 8, 10, 12: day = 31 //fallthrough 执行完当前分支 继续向下执行 case 2: day = 28 case 4, 6, 9, 11: day = 30 default: day = -1 } fmt.Println(day) }
- 浮点型因为精度问题可能在switch中认为是同一个值
func main() { pi := 3.14 //浮点型因为精度问题可能在switch中认为是同一个值 switch pi { case 3.140000000000000000019999999: fmt.Println(pi) case 3.14: fmt.Println(pi) } }
- switch后面不跟条件判断,直接在case内进行判断
像if语句那样去进行判断
package main import ( "fmt" ) func main() { score := 0 fmt.Scan(&score) switch { case score > 700: fmt.Println("我要上蓝翔") case score < 700: fmt.Println("我要去搬砖") } }
2 循环结构语句
- for语句
语法结构如下:
for 表达式1;表达式2;表达式3 {
//循环体
}表达式1 :定义一个循环的变量,记录循环的次数
表达式2:一般为循环条件,循环多少次
表达式3:一般为改变循环条件的代码,使循环条件终有不再成立
循环体:重复要做的事情package main import "fmt" func main() { sum := 0 //循环体计算1-100的和 for i := 1; i <= 100; i++ { sum += i } fmt.Println(sum) }for 表达式1;表达式2;表达式3{
代码
}
for 表达式{
代码
}
for range 集合{
代码
}package main import "fmt" func main() { //水仙花数 //一个三位数 各个位数的立方和等于本身的数 for i := 100; i <= 999; i++ { a := i / 100 //百位 b := i / 10 % 10 //十位 c := i % 10 //个位 if a*a*a+b*b*b+c*c*c == i { fmt.Println(i) } } }
- 嵌套循环
循环语句之间可以相互嵌套:
for 循环条件{
for 循环条件{
//执行代码
} }package main import "fmt" func main() { //嵌套循环 //外层执行一次 内层执行一周期 for i := 0; i < 100; i++ { for j := 0; j < 50; j++ { fmt.Printf("外层=%d 内层=%d\n", i, j) } } }
- 冒泡排序
package main import "fmt" func main() { //冒泡排序 比较两个相邻数据元素 满足条件 交换数据位置 slice := [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} //外层控制行,表示要执行的次数 for i := 0; i < len(slice); i++ { //内存控制列 表示比较次数 for j := 0; j < len(slice); j++ { //比较两个相邻元素 大于号:升序排序 小于号:降序排序 if slice[j] < slice[i] { //交换数据的值 = 实现多重赋值 slice[j], slice[i] = slice[i], slice[j] } } } fmt.Println(slice) }
- 跳出语句
- break语句
在循环语句中可以使用break跳出语句:
当它出现在循环语句中,作用是跳出当前内循环语句,执行后面的代码。
当它出现在嵌套循环语句中,跳出最近的内循环语句,执行后面的代码。
- continue语句
在循环语句中,如果希望立即终止本次循环,并执行下一次循环,此时就需要使用continue语句。
break跳出
#内层 j==5 package main import "fmt" func main(){ //break 跳出循环 for i := 0 ; i < 10 ; i++{ for j := 0 ; j< 10 ; j++{ if j==5{ break } fmt.Println(i,j) } } } 执行到j==5时内层终止循环,但是外层继续执行循环,最终结果为[0-9][0-4]#外层 i==5 package main import "fmt" func main(){ //break 跳出循环 for i := 0 ; i < 10 ; i++{ for j := 0 ; j< 10 ; j++{ if i==5{ break } fmt.Println(i,j) } } } 执行到j==5时内层终止循环,但是外层继续执行循环,最终结果为[0-4][0-9]和[6-9][0-9]continue 结束本次循环 继续下次循环
// 计算1-100偶数的和 package main import "fmt" func main() { //continue 结束本次循环 继续下次循环 //计算1-100偶数的和 sum := 0 for i := 1; i <= 100; i++ { //奇数 if i%2 == 1 { continue } sum += i } fmt.Println(sum) }
- goto 无条件跳转语句
package main import "fmt" func main() { //goto 无条件跳转语句 fmt.Println("性感法师") FLAG: fmt.Println("在线讲课") fmt.Println("轻松就业") goto FLAG fmt.Println("日薪越亿") } //死循环 在线讲课 轻松就业 在线讲课 轻松就业 在线讲课 轻松就业 在线讲课 轻松就业 在线讲课 轻松就业 exit status 2
- goto 不可以跳入循环内部 不可以跳出函数
package main import "fmt" func main() { //goto 不可以跳入循环内部 不可以跳出函数 HERE: for i := 0; i <= 10; i++ { if i == 5 { //break goto HERE } fmt.Println(i) } fmt.Println("程序执行结束...") }
3.优化案例
package main import "fmt" func main0901() { //古代数学家 张丘建 算经 公鸡5钱/只 母鸡3钱/只 小鸡 1钱/3只 需要用百钱买百鸡 //公鸡 20只 //母鸡 33只 //小鸡 100只 count := 0 for i := 0; i <= 20; i++ { for j := 0; j <= 33; j++ { for k := 0; k <= 100; k += 3 { count++ if i+j+k == 100 && i*5+j*3+k/3 == 100 { fmt.Println("公鸡:", i, "母鸡:", j, "小鸡:", k) } } } } fmt.Println("次数:", count) } func main0902() { //古代数学家 张丘建 算经 公鸡5钱/只 母鸡3钱/只 小鸡 1钱/3只 需要用百钱买百鸡 //公鸡 20只 //母鸡 33只 //小鸡 100只 count := 0 for i := 0; i <= 20; i++ { for j := 0; j <= 33; j++ { count++ //小鸡个数=100-公鸡-母鸡 k := 100 - i - j //百鸡 if i*5+j*3+k/3 == 100 && k%3 == 0 { fmt.Println("公鸡:", i, "母鸡:", j, "小鸡:", k) } } } fmt.Println("次数:", count) } //短路算法 if 条件判断 || func test() { //敲7 1-100数字 如果末尾带7 或者十位带7 或者7的倍数 需要敲桌子 正常数字打印 for i := 1; i <= 100; i++ { if i%7 == 0 || i%10 == 7 || i/10 == 7 { fmt.Println("敲桌子") } else { fmt.Println(i) } } } func main() { test() }
4.select永久阻塞
启动协程处理任务,不希望main函数退出,可以使用永久阻塞
func main(){ sever := webhooktesting.NewTestServer(nill) server.StartTLS() fmt.Println("serving on",server.URL) select {} }以上代码不包含case语句和default语句,那么协程将陷入永久阻塞
5.select快速检错
使用管道来传输错误,此时可以使用select语句快速检查管道中是否有错误,避免陷入循环
errCh :=make(chan error,active) jm.deleteJobPods(&job,activePods,errCh) select{ case manmageJobErr = <-errCh: if manageJobErr !=nil{ break } default: //没有错误快速结束检查 }上面的select仅用于尝试从管道中读取错误信息,如果没有错误信息,那么不会陷入阻塞
6.select限时等待
使用管道来管理函数的上下文,此时可以使用select来创建只有一定时效的管道
func waitForStopOrTimeoput(stopCh <- chan struct{},timeout time.Duration) <- chan struct{}{ stopChWithTimeout := make(chan struct{}) go func() { select{ case <- stopCh://自然结束 case <- time.After(timeout)://最长等待时间长 } close(stopChWithTimeout) }() return stopChWithTimeout }该函数返回一个和管道,可用于在函数之间传递,但该管道会在指定时间后自动关闭
.