go-流程控制
介绍
三大流程控制:
- 顺序控制
- 分支控制
- 循环控制
顺序控制
- 程序从上到下逐行地执行,中间没有任何判断和挑战
fmt.Println("-2 & -3 = ", -2&-3) //-4
fmt.Println("-2 ^ 2 = ", -2^2) //-4
fmt.Println("2 | 3 = ", 2|3) // 10 | 11 = 11 = 3
fmt.Println("2 ^ 3 = ", 2^3) // 10 ^ 11 = 01 = 1
fmt.Println("2 >> 1 = ", 2>>1) // 1
fmt.Println("2 << 1 = ", 2<<1) // 4
fmt.Println("-2 << 1 = ", -2<<1) // -4
分支控制
单分支
if 条件表达式 {
执行代码块
}
func main() {
var age int
fmt.Scanln(&age)
if age > 18 {
fmt.Println("You hava liable")
}
}
双分支
if 条件表达式 {
true执行代码块
} else {
false执行代码块
}
var age int = 12
if age > 18 {
fmt.Println("你已经成年了")
} else {
fmt.Println("你还是未成年")
}
多分支
if 条件表达式 {
执行代码块1
} else if 条件表达式 {
执行代码块2
} else [if ...]{
执行代码块3
}
var score float32
fmt.Print("input score : ")
fmt.Scanln(&score)
if score > 90 && score <= 100 {
fmt.Println("A")
} else if score > 80 && score <= 90 {
fmt.Println("B")
} else if score > 70 && score <= 80 {
fmt.Println("C")
} else if score >= 60 && score <= 70 {
fmt.Printf("D")
} else if score < 60 && score >= 0 {
fmt.Println("E")
} else {
fmt.Println("error")
}
嵌套分支
if 条件表达式 {
其他代码1
if 条件表达式 {
执行代码块1
} else {
执行代码快2
}
其他代码2
}
switch分支
- case后是一个表达式(常量、变量、函数返回值)
- case后的各个表达式的值的数据类型,必须和switch的数据类型一致
- case后面可以带多个表达式,使用逗号隔开。
- case后面的表达式若是常量值,则要求不能重复
- case后面不需要带break,程序匹配到一个case后就会执行对相应的代码块,然后退出switch,若一个都匹配不道,则执行default
- default语句可以省略不写
- swtich后可以不带表达式
- switch后可以直接声明/定义一个变量,分号结束,不推荐
- switch穿透fallthrought
- type swtich:switch语句可以被用于type-switch来判断某个interface变量中实际执行的变量类型
switch var1 {
case val1, val2, val3 ... :
...
case val2:
...
default:
...
}
// case 后 默认加了break
switch score {
case 90:
fmt.Println("A")
case 80:
fmt.Println("B")
case 60:
fmt.Println("C")
case 50:
fmt.Println("D")
default:
fmt.Println("E")
}
switch {
case score > 90 && score <= 100:
fmt.Println("A")
case score > 80 && score <= 90:
fmt.Println("B")
case score > 70 && score <= 80:
fmt.Println("C")
case score >= 60 && score <= 70:
fmt.Println("D")
case score >= 0 && score < 60:
fmt.Println("E")
default:
fmt.Println("error")
}
var month int
fmt.Println("input month")
fmt.Scanln(&month)
switch month {
case 3, 4, 5:
fmt.Println("spring")
case 6, 7, 8:
fmt.Println("summer")
case 9, 10, 11:
fmt.Println("automu")
case 12, 1, 2:
fmt.Println("witer")
default:
fmt.Println("error")
}
循环控制
for
for i := 0; i < 20; i++ {
fmt.Println("hello go")
}
// 1. 传统方式1
var sum int = 0
for i := 0; i < 11; i++ {
sum += i
}
fmt.Printf("sum: %v\n", sum) // 55
// 2. 类似于while的for2
sum = 0
var j int = 1
for j <= 10 {
sum += j
j++
}
fmt.Printf("sum: %v\n", sum)
// 3. while(true) 类似
for {
if j == 20 {
break
}
sum += j
j++
}
fmt.Printf("sum: %v\n", sum)
var num []int = []int{1, 2, 3, 4, 5}
// 4. for range 类似 foreach
for index, val := range num {
fmt.Printf("index: %v\n", index)
fmt.Printf("val: %v\n", val)
}
for _, val := range num {
fmt.Printf("val: %v\n", val)
}
var str string = "abcde"
for _, s := range str {
fmt.Printf("s: %c\t", s)
}
// 当存在中文时,for不好使 因为汉字是UTF-8编码,占三个字节。需要scilce或for range
// 但是for range还是 会出现下标+3的问题
var chinese string = "abcd北京"
for i := 0; i < len(chinese); i++ {
fmt.Printf("chinese[i]: %c\n", chinese[i]) // 出现乱码
}
for index, word := range chinese {
fmt.Printf("index: %v\n", index)
fmt.Printf("word: %c\n", word)
}
ss := []rune(chinese)
fmt.Printf("ss: %c\n", ss)
无while和do while
多重(嵌套)循环控制
// 九九乘法表
for i := 1; i <= 9; i++ {
for j := 1; j <= i; j++ {
fmt.Print(j)
fmt.Print(" * ")
fmt.Print(i)
fmt.Print(" = ")
fmt.Print(i * j)
fmt.Printf("\t")
}
fmt.Println("")
}
var n int = 15
for i := 1; i <= n; i++ {
for j := 1; j <= i; j++ {
fmt.Printf("%v * %v = %v\t", j, i, i*j)
}
fmt.Println("")
}
var score [][]int = [][]int{{1, 2, 3, 4, 5}, {11, 22, 33, 44, 55}, {11, 12, 13, 14, 15}}
var sum int = 0
var classNum int = len(score)
var classAvg [3]float64
for i := 0; i < classNum; i++ {
var classSum int = 0
for j := 0; j < len(score[i]); j++ {
sum += score[i][j] // 统计总分
classSum += score[i][j]
}
classAvg[i] = float64(classSum / len(score[i]))
}
fmt.Printf("sum: %v\n", sum)
fmt.Println("avg: ", float64(sum)/15.0)
fmt.Printf("classAvg: %v\n", classAvg)
break
可以为break语句指定一个标签,让代码逻辑退出到那个点。
func main() {
i := 0
var count int = 0
for {
i++
// 偶数跳过
if i%2 == 0 {
continue
}
// rand.Seed(5) // 给定种子
rand.Seed(time.Now().UnixMicro()) // 给定 变量种子
fmt.Printf("%d: %v\n", i, rand.Intn(100)+1)
count++
if i == 99 {
break
}
}
fmt.Printf("count: %v\n", count)
}
func main() {
label1:
for i := 0; i < 20; i++ {
label2:
for j := 0; j < 20; j++ {
label3:
for k := 0; k < 20; k++ {
if k == 1 {
break label1 // 直接终止label1 : i的for循环
} else if k == 3 {
break label2 // 直接终止laben2 : j的for循环
}
if k == 5 {
break // 终止本层循环
}
break label3 // 直接终止laben3 : k的for循环 / 本层循环
}
}
}
}
continue
- continue语句用于结束本次循环,继续执行下一次循环
- continue语句出现在多层嵌套循环语句体中时,可以通过标签指明要跳过的是哪一层循环
func main() {
label1:
for i := 0; i < 5; i++ {
label2:
for j := 0; j < 5; j++ {
if j == 4 {
continue label1
}
if j == 2 {
continue label2
}
fmt.Printf("j: %v\n", j)
}
fmt.Printf("i: %v\n", i)
}
}
// 练习
for i := 1; i <= 100; i++ {
if i%2 == 0 {
continue
}
fmt.Printf("i: %v\t", i)
}
fmt.Println("")
var input int
var count1 int = 0
var count2 int = 0
for {
fmt.Scanln(&input)
if input == 0 {
break
} else if input > 0 {
count1++
} else {
count2++
}
}
fmt.Printf("positive: %v\n", count1)
fmt.Printf("negative: %v\n", count2)
goto-基本不用
- golang的goto语句可以无条件地跳转到程序中指定的行
- goto语句通常与条件语句配合使用。可用来实现条件建议,跳出循环体等功能
- 在go程序设计中一般不主张使用goto语句,以免造成程序流程的混乱,使理解和调试程序都产生困难
label1:
fmt.Println("1")
fmt.Println("2")
fmt.Println("3")
fmt.Println("4")
fmt.Println("5")
fmt.Println("6")
fmt.Println("7")
fmt.Println("8")
fmt.Println("9")
goto label1
return
- 直接终止当前函数,返回值,若执行后,不再执行其他语句