# Golang 流程控制
# 一、条件语句
# 1. if
- 无需括号
- if 条件上可以有初始化语句
if a < 20 {
//..
} else if a > 40 {
//..
} else {
//...
}
- if 条件上可以有初始化语句,常用场景如下:
if err := callAMethod(); err != nil {
// handle error
}
# 二、选择语句
# 1. switch
switch 有两种:
- 表达式 switch:普通的 switch,用来代替多个 if else
- 类型 switch:用来判断传入的数据类型
# 1.1 表达式 switch
package main
import "fmt"
func main() {
grade := "B"
marks := 90
switch marks {
case 90:
grade = "A"
case 80:
grade = "B"
case 70:
grade = "C"
case 60:
grade = "D"
default:
grade ="E"
}
fmt.Printf("Your grade is %s\n", grade)
}
# 1.2 类型 switch
package main
var x interface{}
func main() {
x = 1
switch i:= x.(type) { //取出 x 的类型,swicth 同样支持在表达式处进行初始化
case nil:
//...
case int:
//...
case float64:
//...
case bool:
//...
case string:
//...
default:
//...
}
}
# 2. select
select 语句用于配合 channel 的读写操作,用于多个 channel 的并发读写操作。
switch 是从上往下按顺序执行,而 select 是随机选择一个 case 来判断,直到匹配其中的一个 case。
package main
import "fmt"
func main() {
a := make(chan int, 1024) //初始一个 int channel
b := make(chan int, 1024)
for i := 0; i < 10; i++ {
fmt.Printf("第 %d 次", i)
a <- 1 //将一个值为 1 的 int 数据扔进 a
b <- 1
//select 语句
select {
case getA := <- a: //从 a 中取数据
fmt.Println("from a", getA)
case getB := <- b:
fmt.Println("from b", getB)
}
}
}
# 三、循环语句
# 1. for
for 语句后面跟 3 个子语句:
- 初始化子语句
- 条件子语句
- 后置子语句
for i := 1; i < 10; i++ {
fmt.Println("", i)
}
# 2. range
每一个 for 语句都可以使用一个特殊的 range 语句,其作用类似于迭代器,用于轮询数组或者切片值中的每一个元素,也可以用于轮询字符串中的每一个字符,以及字典值中的每一个键值对,甚至还可以持续读取一个通道类型值中的元素。
右边表达式返回的类型 | 第一个值 | 第二个值 |
---|---|---|
string | index | str[index],返回类型为 rune |
array/slice | index | arr[index] |
map | key | m[key] |
channel | element |
m := make(map[string]string)
m["1"] = "1"
m["2"] = "2"
m["3"] = "3"
for k, v := range m {
fmt.Printf("key is %s, value is %s", k, v)
}
# 四、延迟语句
# 1. defer
Go 语言中还有一个延迟语句 defer, defer 用于延迟调用指定函数,defer 关键字只能出现在函数内部。
func main() {
defer fmt.Println("World")
fmt.Println("Hello")
}
会返回:
Hello
World
defer 有 2 大特点:
defer 会在函数 return 之前,以及函数 panic 的时候执行
defer 的调用顺序有“栈”的感觉,先写的后调用
defer fmt.Println("1") defer fmt.Println("2") defer fmt.Println("3") //最后是输出 3 2 1
因为 defer 的特点,可以把 defer 语句用于回收资源、清理结尾等工作。
# 五、跳转语句
# 1. Label
Go 支持给 for、switch 或 select 等流程控制代码块打上标签,配合标签可以方便跳转到某一个地方继续执行带啊,有助于提高编程效率。
L1:
handleError()
# 2. break
break 打断当前流程控制。
打断 for 循环
for i := 1; i <= 5 ; i++ { if i >= 3 { break //跳出 for 循环 } }
打断某个代码块
LOOP1: for { x := 1 switch { case x > 0: fmt.Println("A") break LOOP1 //跳到 LOOP1 代码块以外 case x == 1: fmt.Println("B") default: fmt.Println("C") } }
# 3. continue
continue 用于跳转到指定代码块位置继续执行任务,continue 仅能用于 for 语句。
进入下一轮 for 循环
for i := 1; i <= 5 ; i++ { if i >= 3 { continue //立刻进入下一轮 for 循环 } }
回到某个位置继续执行
LOOP1: for { x := 1 switch { case x > 0: fmt.Println("A") continue LOOP1 //跳到 LOOP1 代码块继续执行 case x == 1: fmt.Println("B") default: fmt.Println("C") } }
# 4. goto
goto 用于跳转到某个标签。
func main() {
i := 1
for {
i ++
if i > 10 {
goto END //跳到 END 标签处执行
}
}
END:
fmt.Println("end")
}