go语言流程控制详解
go语言分支结构
if特殊写法:
if err := Connect(); err != nil {
fmt.Println(err)
return
}
Connect 是一个带有返回值的函数,err:=Connect() 是一个语句,执行 Connect 后,将错误保存到 err 变量中。
err != nil 才是 if 的判断表达式,当 err 不为空时,打印错误并返回。
这种写法可以将返回值与判断放在一行进行处理,而且返回值的作用范围被限制在了if、else语句组合中。
提示:
在编程中,变量的作用范围越小,所造成的问题可能性越小,每一个变量代表一个状态,有状态的地方,状态就会被修改,函数的局部变量只会影响一个函数的执行,但全局变量可能会影响所有代码的执行状态,因此限制变量的作用范围对代码的稳定性有很大的帮助。
for中的初始语句--开始循环时执行的语句
初始语句是在第一次循环前执行的语句,一般使用初始语句执行变量初始化,如果变量在此处被声明,其作用域将被局限在这个 for 的范围内。
初始语句可以被忽略,但是初始语句之后的分号必须要写,代码如下:
func main() {
step := 2
for ; step > 0; step-- {
fmt.Println(step)
}
}
这段代码将step放在for的前面进行初始化,for中没有初始语句,此时step的作用域就比在for初始语句中声明要大。
for中的结束语句--每次循环结束时执行的语句
在结束每次循环前执行的语句,如果循环被 break、goto、return、panic 等语句强制退出,结束语句不会被执行。
go语言输出九九乘法表
func main() {
for i := 1; i <= 9; i++ {
for j := 1; j <= i; j++ {
fmt.Printf("%d*%d=%d\t", j, i, j*i)
}
fmt.Println()
}
}
输出结果
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
go语言键值循环
for key, val := range coll {
...
}
需要注意的是:val始终为集合中对应索引的值拷贝,因此它一般只具有只读性质,对它所做的任何修改都不会影响到集合中原有的值,一个字符串是unicode编码的字符(或称之为rune)集合,因此也可以用它来迭代字符串。
for range遍历的返回值有一定的规律
- 数组、切片、字符串返回索引和值。
- map 返回键和值。
- 通道(channel)只返回通道内的值。
- 遍历数组、切片——获得索引和值
func main() {
ch := make(chan int)
go func() {
defer close(ch)
for i := 0; i < 10; i++ {
ch <- i
}
}()
for val := range ch {
fmt.Println(val)
}
}
for循环遍历字符串--获得字符
func main() {
str := "hello 你好"
for key, value := range str {
fmt.Println(key, value, reflect.TypeOf(value))
}
}
代码中的变量 value,实际类型是 rune 类型,以十六进制打印出来就是字符的编码。
总结for功能:
- Go语言的for包含初始化语句,条件表达式,结束语句,这三个部分均可缺省。
- for range支持对数组、切片、map、channel、字符串操作。
- 在需要时,可以使用匿名变量对for range的变量进行选取。
Go语言switch语句
- 一分支多值
当出现多个case要放在一起的时候,可以写成这样:
func main() {
a := 999
switch a {
case 88, 99:
fmt.Println("a等于88或99")
default:
fmt.Println("a是错的")
}
}
- 分支表达式
case后不仅仅只是常量,还可以和if一样添加表达式:
func main() {
a := rand.Intn(10)
switch {
case a >= 80:
fmt.Println("优秀")
case a >= 60:
fmt.Println("及格")
default:
fmt.Println("不及格")
}
}
注意这种情况的switch后面不需要跟判断变量
3. 跨越case的fallthrough--兼容c语言的case设计
在Go语言中 case 是一个独立的代码块,执行完毕后不会像C语言那样紧接着执行下一个 case,但是为了兼容一些移植代码,依然加入了 fallthrough 关键字来实现这一功能,代码如下:
func main() {
//a := rand.Intn(100)
a := 88
switch {
case a >= 80:
fmt.Println("优秀")
fallthrough
case a >= 60:
fmt.Println("及格")
default:
fmt.Println("不及格")
}
}
新编写的代码,不建议使用 fallthrough。
go语言goto语句
下面这段代码在满足条件时,需要连续退出两层循环,使用传统的编码方式如下:
func main() {
outQuit := false
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
if j >= 5 {
outQuit = true
break
}
fmt.Println(i, j)
}
if outQuit {
break
}
}
}
将上面的代码使用Go语言的 goto 语句进行优化:
func main() {
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
if j >= 5 {
goto loop
}
fmt.Println(i, j)
}
}
loop:
}
使用 goto 语句后,无须额外的变量就可以快速退出所有的循环。
go语言break(跳出循环)
Go语言中 break 语句可以结束 for、switch 和 select 的代码块,另外 break 语句还可以在语句后面添加标签,表示退出某个标签对应的代码块,标签要求必须定义在对应的 for、switch 和 select 的代码块上。
跳出指定循环:
func main() {
outerQuit:
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
switch j {
case 2:
fmt.Println(i, j)
break outerQuit
case 3:
fmt.Println(i, j)
break outerQuit
}
}
}
}
go语言continue
Go语言中 continue 语句可以结束当前循环,开始下一次的循环迭代过程,仅限在 for 循环内使用,在 continue 语句后添加标签时,表示开始标签对应的循环,例如:
func main() {
outerQuit:
for i := 0; i < 2; i++ {
for j := 0; j < 10; j++ {
switch j {
case 2:
fmt.Println(i, j)
continue outerQuit
}
}
}
}
输出结果:
0 2
1 2
第 14 行将结束当前循环,开启下一次的外层循环,而不是第 10 行的循环。