流程控制是各种编程语言控制逻辑走向和执行次序的交通灯
Go 语言常用流程控制if 和 for ,(没有 while),还有为了简化代码、降低代码重复而生的结构 switch 和 goto 语句,属于扩展类的流程控制。
条件判断语句(if)
func main() {
var a int = 8
var b int = 10
var c int = 17
ifFunc(a)
ifFunc(b)
ifFunc(c)
}
//一般写法
func ifFunc(a int) {
if a > 10 {
fmt.Println(a, ">10")
} else if a == 10 {
fmt.Println(a, "=10")
} else {
fmt.Println(a, "<10")
}
}
OutPut Result:
8 <10
10 =10
17 >10
// 特殊写法
if err:=Connect();err != nil{
log.Fatal(err)
return
}
特殊写法,将返回值与判断写在同一行,而且返回值的作用范围被限制在 if、else 语句组合内,这样缩小了变量的作用范围,因为,在编程中,变量在其实现了变量功能后,作用影响范围越小,所造成的问题可能性越小。
每一个变量代表一个状态,有状态的地方(作用范围),状态就会被修改,函数的局部变量只会影响单个函数的执行结果,但是全局变量可能影响整个程序(所有代码)的执行状态,因此,限制变量的作用范围对代码的稳定性有很大的帮助。
判断语句(switch):多条件语句的简化(批量 if 语句)
func switchFunc(v interface{}) {
// 使用断言判断类型
switch v.(type) {
case int, int8: // 一分支多值
fmt.Println("int")
case string:
fmt.Println("string")
default:
fmt.Println("Don't Know Type")
}
}
// OutPut:
int
string
Don't Know Type
- 默认情况下switch语句是执行完相应的代码就会退出整个switch 代码块,即可以不需要像C、C++那样使用 break 与语句来结束。
- 如果在执行完当前分支后,希望继续执行下面分支的代码,可以使用 fallthrough 关键字实现。
- fallthrough 不会判断下一条分支语句的表达式的是否为真,而强制执行下一条分支代码。
func main() {
switch a := 1; {
case a == 1:
fmt.Println("1")
fallthrough
case a == 2:
fmt.Println("2")
// fallthrough
case a == 3:
fmt.Println("3")
case a == 4:
fmt.Println("4")
fallthrough
default:
fmt.Println("default")
}
}
如上所示代码块,结果会输出1 2,由于case 1 ,使用 fallthrough 关键字,因此其不会判断下一条分支的是否符合判断,会被强制执行,因此输出 2 ,但是不会执行 case 3。
func forFunc() {
var slice = make([]int, 10)
// 基本用法
for i := 0; i < 10; i++ {
slice[i] = i + 1
}
// 基本遍历切片
for i := 1; i <= 10; i++ {
fmt.Print(slice[i-1], "\t")
if i%4 == 0 {
fmt.Println()
}
}
fmt.Println()
// range 遍历切片
for i, v := range slice {
fmt.Print(i, ":", v, "\t")
if (i+1)%4 == 0 {
fmt.Println()
}
}
fmt.Println()
//无限循环
const N = 9
var i int
for {
if i > N {
break
}
// TODO
i++
}
}
// OutPut Result :
1 2 3 4
5 6 7 8
9 10
0:1 1:2 2:3 3:4
4:5 5:6 6:7 7:8
8:9 9:10
示例:利用for 循环生成九九乘法表:
func NineTable() {
for i := 1; i < 10; i++ {
for j := 1; j <= i; j++ {
fmt.Printf("%d*%d=%2d \t", j, i, j*i)
}
// 手动换行
fmt.Println()
}
}
OutPut Result:
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
// 跳出多层循环
func gotoLoop1() string {
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
if j == 5 {
fmt.Println(i, j)
// 跳转到 breakHere 标签
goto breakHere
}
}
}
return "return"
breakHere:
return "done"
}
func errNomal() {
err := FirstcheckErr()
if err != nil {
fmt.Println(err)
exitProcess()
return
}
err = secondcheckErr()
if err != nil {
fmt.Println(err)
exitProcess()
return
}
fmt.Println("done")
}
func errGoto() {
err := FirstcheckErr()
if err != nil {
goto onExit
}
err = secondcheckErr()
if err != nil {
goto onExit
}
fmt.Println("done")
return
onExit:
fmt.Println(err)
exitProcess()
}
func breakLoop() {
// 结束对应的循环
OUTLOOP:
for i := 1; i < 5; i++ {
for j := 0; j < 5; j++ {
switch j {
case 3:
fmt.Println(i, j)
break OUTLOOP
case 4:
fmt.Println(i, j)
break OUTLOOP
}
}
}
}
// Result:
//1 3
func continueLoop() {
// 结束对应的循环
InerLOOP:
for i := 0; i < 2; i++ {
for j := 0; j < 5; j++ {
switch j {
case 2:
fmt.Println(i, j)
continue InerLOOP
}
}
}
}
// Result:
0 2
1 2