控制流
if / for / switch,以及 defer 初识。
if
条件不用括号;支持初始化语句(作用域限于 if/else):
if x := 42; x > 0 {
fmt.Println("positive")
} else if x == 0 {
fmt.Println("zero")
} else {
fmt.Println("negative")
}
错误处理常见写法:
if err != nil {
return err
}
for
Go 只有 for,没有 while。三种形态:
// 经典三段
for i := 0; i < 3; i++ {
fmt.Println(i)
}
// 条件循环(≈ while)
n := 3
for n > 0 {
n--
}
// 无限循环
for {
break
}
range 遍历:
s := []string{"a", "b"}
for i, v := range s {
fmt.Println(i, v)
}
for i := range s { // 只要下标
_ = i
}
for _, v := range s { // 只要值
_ = v
}
break / continue 可用;可用标签跳出外层循环(少用,保持可读)。
switch
默认不 fallthrough(与 C 不同);可无表达式:
switch day := 3; day {
case 1, 2:
fmt.Println("early")
case 3:
fmt.Println("mid")
default:
fmt.Println("other")
}
day := 3
switch {
case day < 0:
fmt.Println("invalid")
case day < 7:
fmt.Println("week")
}
需要贯穿时显式写 fallthrough(少用)。类型 switch 在处理 interface{} / any 时很常见(进阶接口篇)。
defer
defer 把调用推迟到当前函数返回前执行,常用于关闭资源:
func read() error {
f, err := os.Open("a.txt")
if err != nil {
return err
}
defer f.Close()
// 使用 f ...
return nil
}
注意:
- 多个
defer:后进先出(LIFO) - 参数在 defer 注册时求值
- 适合 unlock、cancel、close;别堆太复杂的逻辑
func demo() {
for i := 0; i < 3; i++ {
defer fmt.Println(i) // 打印 2 1 0
}
}
小结
if可带短变量声明;错误立刻返回- 循环统一用
for/range switch默认不贯穿defer保证清理,注意 LIFO 与求值时机