流程控制
-
if else分支结构
else必须写在}后面
package main import "fmt" ///基本格式 // if 表达式1 { // 分支1 // } else if 表达式2 { // 分支2 // } else{ // 分支3 // } //{}是必须的,即使分支语句只有一句 func main() { age := 19 if age > 18 { fmt.Println("成年") } else { fmt.Println("未成年") } //多条件判断 if age > 35 { fmt.Println("中年") } else if age > 18 { fmt.Println("青年") } else { fmt.Println("小朋友") } //if语句的特殊写法,在if前添加一个执行语句,根据变量值进行判断 //但注意score在if的作用域中,只有在if的范围内有效,在外面没有这个score //该方法可以帮助减少程序内存占用 if score := 65; score >= 90 { fmt.Println("A") } else if score > 75 { fmt.Println("B") } else { fmt.Println("C") } // fmt.Println(score)出错,因为在作用域外没有score }
-
for循环
package main import "fmt" func main() { // 基本格式 // for 初始语句;条件表达式;结束语句{ // 循环体语句 // } //{}是不能省略的, for i := 0; i < 10; i++ { fmt.Println(i) } //省略第一个赋值 j := 20 for ; j > 10; j-- { fmt.Println(j) } //省略第一个赋值和后续条件 k := 10 for k < 20 { fmt.Println(k) k++ } //可以看出for就是一个包含了赋值,判断,计数条件为一体的函数 //for range循环用于遍历数组、切片、字符串、map 及通道 //数组、切片、字符串返回索引和值,map返回键和值,通道(channel)只返回通道内的值。 //如果只想要值或者索引,可以用_来接收另一个值 s := "Hello卡卡" for i, v := range s { //i是索引,v是字符的值 fmt.Printf("%d:%c\n", i, v) //字符用占位符将int32输出为相应字符的值 } //九九乘法表 for i := 1; i < 10; i++ { for j := 1; j <= i; j++ { fmt.Printf("%d*%d=%d\t", i, j, i*j) } fmt.Println() } }
-
for range
for range
在遍历时会新开一个内存在上面拷贝遍历的每一个值,并且会重用地址,后续遍历到的值覆盖前面的值。package main import "fmt" type student struct { name string age int } func main() { m := make(map[string]*student) stus := []student{ {name: "小王子", age: 18}, {name: "娜扎", age: 23}, {name: "大王八", age: 9000}, } fmt.Printf("student1:%p\n", &stus[0]) fmt.Printf("student2:%p\n", &stus[1]) fmt.Printf("student3:%p\n", &stus[2]) //for range循环会新开一个地址,并在同一个地址上拷贝遍历到的每一个value,也就是重用地址 //并且存在该地址上的值会一直保存到程序结束 for _, stu := range stus { m[stu.name] = &stu fmt.Printf("%p\n", &stu) } //因为会重用地址,所以这个地址上会先存储小王子,娜扎,大王八,由于循环中存储的地址都一样,所以最后输出的值都是最后保存的大王八 for k, v := range m { fmt.Println(k, "=>", v.name) } //使用长度遍历,将原本stus的地址复制到map中 for i := 0; i < len(m); i++ { m[stus[i].name] = &stus[i] fmt.Printf("student1:%p\n", &stus[i]) } for k, v := range m { fmt.Println(k, "=>", v.name) } }
-
switch case
package main import "fmt" //switch简化大量判断 func main() { finger := 3 //标准格式 switch finger { case 1: fmt.Println("大拇指") case 2: fmt.Println("食指") case 3: fmt.Println("中指") case 4: fmt.Println("无名指") case 5: fmt.Println("小拇指") default: fmt.Println("无效的输入!") } //可以规定一个case有多个值,每个值用,隔开 //也可以再switch先赋值再判断 switch n := 7; n { case 1, 3, 5, 7, 9: fmt.Println("奇数") case 2, 4, 6, 8: fmt.Println("偶数") default: fmt.Println(n) } //也可以将case后用判断语句来代替值,从而引入大小于关系 age := 100 switch { case age < 25: fmt.Println("好好学习吧") case age > 25 && age < 35: fmt.Println("好好工作吧") case age > 60: fmt.Println("好好享受吧") default: fmt.Println("活着真好") } //fallthrough可以在执行完当前满足的条件后再执行下一个case,主要为了兼容c语言 //不建议使用 s := "a" switch { case s == "a": fmt.Println("a") fallthrough case s == "b": fmt.Println("b") case s == "c": fmt.Println("c") default: fmt.Println("...") } //输出a和b }
-
break和continue
package main import "fmt" func main() { //break跳出当前循环 for i := 0; i < 10; i++ { if i == 5 { break } fmt.Println(i) } //break可以在语句后添加标签,直接退出标签对应的代码块,标签只能用在对应的for,select,switch的代码块上 //主要为了方便一次性跳出多重循环 BREAKDEMO1: for i := 0; i < 10; i++ { for j := 0; j < 10; j++ { if j == 2 { break BREAKDEMO1 } fmt.Printf("%v-%v\n", i, j) } } fmt.Println("...") //continue跳过此次循环,直接执行下一次 for i := 0; i < 10; i++ { if i == 5 { continue } fmt.Println(i) } //同样类似可以在continue后加上标签,表示开始标签对应的循环 }
-
goto(少用)
package main import ( "fmt" ) // goto可以通过标签进行代码之间的无条件跳转,可以快速跳出多层循环 //跳出多层循环 func main() { flag := false for i := 0; i < 10; i++ { for j := 0; j < 10; j++ { if j == 2 { flag = true break } fmt.Printf("%d-%d\n", i, j) } if flag { fmt.Println("结束for循环") break } } //利用goto进行简化代码 for i := 0; i < 10; i++ { for j := 0; j < 10; j++ { if j == 2 { // 设置退出标签 goto breakTag } fmt.Printf("%v-%v\n", i, j) } } // 标签 breakTag: fmt.Println("结束for循环") }