Skip to main content

控制流

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
}
}

小结

  1. if 可带短变量声明;错误立刻返回
  2. 循环统一用 for / range
  3. switch 默认不贯穿
  4. defer 保证清理,注意 LIFO 与求值时机

上一篇:类型与复合类型 · 下一篇:函数与方法