Golang 中流程控制简单介绍 Link to heading

Golang 中包含三种基本的流程控制代码块:

  • if-else条件分支代码块;
  • for循环代码块;
  • switch-case多条件分支代码块;

同时 Golang 还提供了几种特定类型所使用的流程控制代码块:

  • 容器类型相关的for-range循环代码块。
  • 接口类型相关的type-switch多条件分支代码块。
  • 通道类型相关的select-case多分支代码块。

和大部分现代语言一样,Golang 提供了breakcontinuegoto、及fallthrough流程跳转关键字

下面来介绍三种基本流程控制语句的使用:

if-else条件分支控制代码块 Link to heading

if-else 语句同大部分语言一致,一个完整的if-else条件分支控制语句的写法如下:

if initStatement; condition{
  // code
} else {
  // code
}

// initStatement 必须使用简单语句
// initStatement 可省略


// if a := 2; a > 3{
//   fmt.Println("大于三")
// } else {
//   fmt.Println("小于三")
// }

代码演示如下:

// go_control_flow.go

package main

import (
	"fmt"
	"math/rand"
)

func printOdd(n uint32) {
	if n%2 == 0 {
		fmt.Println(n, "为偶数")
	} else {
		fmt.Println(n, "为奇数")
	}
}

func printFuzzBuzz(n uint32) {
	if n%3 == 0 && n%5 == 0 {
		fmt.Println("FuzzBuzz")
	} else if n%3 == 0 {
		fmt.Println("Fuzz")
	} else if n%5 == 0 {
		fmt.Println("Buzz")
	} else {
		fmt.Println("Unknown")
	}
}

func main() {
	if a := rand.Int(); a > 1 {
		fmt.Println("2 > 1")
	} else if a == 1 {
		fmt.Println("a == 1")
	}

	// 下面这行输出 会编译错误
	// 未声明 变量 a
	// fmt.Println(a)
	// 有由此可知 if 语句中 initStatement 说声明的变量只在当前if语句代码块可见
	// 随着 if 语句的结束 说声明的变量也将结束其生命周期

	// 省略 initStatement

	c := rand.Uint32()
	printOdd(c)
	printFuzzBuzz(c)

}
$ go run go_control_flow.go

2 > 1
2561291343 为奇数
Fuzz

for循环代码块 Link to heading

Golang 中 for 循环代码同样与其他语言类似,但在在 Ruby 中我们更多的使用each.

for 循环语句较为简单,下面使用代码及注释的方式进行介绍:

// go_for.go
package main

import "fmt"

func for01() {
	fmt.Println("========= 省略初始化语句=========")

	i := 0
	for ; i < 10; i++ {
		fmt.Println(i)
	}
}

func for02() {
	fmt.Println("========= 省略步尾语句=========")

	i := 0
	for i < 10 {
		fmt.Println(i)
		i++
	}
}

func for03() {
	// break 关键字用于提前跳出循化,不执行步尾语句
	fmt.Println("========= 全部省略=========")
	i := 0
	for {
		if i >= 10 {
			break
		}

		fmt.Println(i)
		i++
	}
}

func for04() {
	// continue 关键字提前结束当前循环,仍执行步尾语句
	fmt.Println("========= continue关键字=========")
	for n := 0; n < 10; n++ {
		if n%2 != 0 {
			continue
		}

		fmt.Println(n)
	}
}

func main() {

	// 依次输出数字 0-9
	// for n := 0; n < 10; n++ {
	// 	fmt.Println(n)
	// }

	// 上述代码块为for循环语句的基本实现
	// 其中for为关键字,
	// n:=0 为初始化语句;
	// n < 10 为条件表达式;
	// n++为步尾语句;
	// 每个for循环中,初始化语句将率先执行,并且只会执行一次
	// 当每次循环开始时,将对条件表达式进行判断,若为false则结束循环
	// 当每次循环结束时,将执行步尾语句.

	// 以上提到的三个部分均可被省略

	//省略初始化语句s
	for01()

	// 省略步尾语句
	for02()

	// 全部省略
	for03()

	// continue 关键字
	for04()

}
$ go run go_for.go

========= 省略初始化语句=========
0
1
2
3
4
5
6
7
8
9
========= 省略步尾语句=========
0
1
2
3
4
5
6
7
8
9
========= 全部省略=========
0
1
2
3
4
5
6
7
8
9
========= continue关键字=========
0
2
4
6
8

switch-case流程控制代码块 Link to heading

switch 语句中 case 执行完成后会立即退出,当我们希望 在当前 case 语句中执行完成之后,仍然执行该 case 语句的下方第一个 case 时,可以使用 fallthrough 关键字如下 switch02

// go_switch.go
package main

import (
	"fmt"
	"math/rand"
)

func switch01() {
	switch n := rand.Intn(100); n % 9 {
	case 0:
		fmt.Println("被9整除")
	case 1, 3:
		fmt.Println("余 1, 3")
	// case 3: 这里编译失败 因为 3 以及在上一个case语句出现
	// 	fmt.Println("余 3")
	case 5:
		fmt.Println("余 5")
	case 7:
		fmt.Println("余 7")
	default:
		fmt.Println("余 2, 4, 6, 8, 9")
	}
}

func switch02() {
	// switch 语句中case 执行完成后会立即退出
	// 当我们希望 在当前case语句中执行完成之后
	// 仍然执行该case语句的下方第一个case时
	// 可以使用 fallthrough 关键字
	switch n := 54; n % 9 {
	case 0:
		fmt.Println(n)
		fallthrough
	case 1, 3:
		n := 99
		fmt.Println(n)
	case 5:
		fmt.Println(n)
	case 7:
		fmt.Println(n)
	default:
		fmt.Println(n)
	}
}

func main() {
	switch01()
	switch02()
}
$ go run go_switch.go

7
54
99

再使用fallthrough关键字时需要注意如下亮点

  • 一条fallthrough语句必须为一个分支代码块中的最后一条语句。
  • 一条fallthrough语句不能出现在一个switch-case流程控制中的最后一个分支代码块中。