Golang流程控制
流程控制决定程序按什么顺序执行。Go 语言的流程控制语法比较少,核心就是 if、for、switch、select、defer 以及少量跳转语句。
整体结构
mermaid
flowchart TD
A[程序开始] --> B{条件判断}
B -->|满足| C[执行分支 A]
B -->|不满足| D[执行分支 B]
C --> E{是否需要循环}
D --> E
E -->|是| F[for 循环]
F --> E
E -->|否| G[程序结束]if 条件判断
Go 的 if 不需要小括号,但代码块必须使用大括号。
go
age := 18
if age >= 18 {
fmt.Println("成年人")
} else {
fmt.Println("未成年人")
}if 可以在条件前执行一段短语句,这个变量只在当前 if 结构内有效。
go
if score := 90; score >= 60 {
fmt.Println("及格")
}这种写法适合把临时变量限制在很小的作用域内,避免变量污染外层逻辑。
for 循环
Go 只有 for 一种循环关键字,但可以写出多种效果。
传统循环
go
for i := 0; i < 10; i++ {
fmt.Println(i)
}条件循环
go
count := 0
for count < 10 {
count++
}无限循环
go
for {
// 常用于服务监听、任务轮询
}range 遍历
range 常用于遍历数组、切片、map、字符串和 channel。
go
nums := []int{10, 20, 30}
for index, value := range nums {
fmt.Println(index, value)
}遍历 map 时顺序不固定,不要依赖 map 的遍历顺序。
switch 分支
Go 的 switch 默认每个 case 执行后自动结束,不需要写 break。
go
level := "A"
switch level {
case "A":
fmt.Println("优秀")
case "B":
fmt.Println("良好")
default:
fmt.Println("未知")
}如果需要继续执行下一个 case,可以使用 fallthrough,但实际项目中要谨慎使用,因为它会降低代码可读性。
select
select 专门用于处理多个 channel 的收发操作。哪个 channel 先准备好,就执行哪个分支。
go
select {
case msg := <-ch1:
fmt.Println("ch1:", msg)
case msg := <-ch2:
fmt.Println("ch2:", msg)
case <-time.After(time.Second):
fmt.Println("timeout")
}mermaid
flowchart TD
A[进入 select] --> B{哪个 channel 就绪?}
B -->|ch1| C[执行 ch1 分支]
B -->|ch2| D[执行 ch2 分支]
B -->|都未就绪且有 timeout| E[执行超时分支]defer
defer 会把函数推迟到当前函数返回前执行,常用于资源释放。
go
file, err := os.Open("demo.txt")
if err != nil {
return err
}
defer file.Close()多个 defer 的执行顺序是后进先出。
go
defer fmt.Println("1")
defer fmt.Println("2")
defer fmt.Println("3")
// 输出顺序:3 2 1break、continue、goto
| 语句 | 作用 |
|---|---|
| break | 跳出当前循环或 switch |
| continue | 跳过本轮循环,进入下一轮 |
| goto | 跳转到指定标签 |
goto 在业务代码中不常用,容易破坏代码结构。一般只有在需要统一跳出多层逻辑时才考虑。
实战建议
if条件尽量保持简单,复杂条件可以提前拆成有语义的变量。- 遍历 map 不要依赖顺序。
defer适合关闭文件、释放锁、恢复 panic。select常和 goroutine、channel 一起使用,适合超时控制和多路监听。- 能用清晰分支表达时,不要使用
goto。
下一步可以继续看 函数 和 goroutine与channel。
