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语句

  1. 一分支多值
    当出现多个case要放在一起的时候,可以写成这样:
func main() {
	a := 999
	switch a {
	case 88, 99:
		fmt.Println("a等于88或99")
	default:
		fmt.Println("a是错的")
	}
}
  1. 分支表达式
    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 行的循环。

posted @ 2022-08-31 16:52  专职  阅读(39)  评论(0编辑  收藏  举报