讲解
if 是程序的第一块流程控制积木:条件为真就执行大括号里的代码。Go 的 if 有两个显著的外观特征:条件不用圆括号包起来,而大括号必须写(哪怕只有一行)。这两个规定消除了大量风格争论,也让代码更易读。
Go 的 if 支持一个其他语言少有的「初始化语句」:if n := len(s); n > 10 { ... }。分号前声明的变量只在整个 if-else 链内部有效,特别适合「先算个值、马上判断、之后不再需要」的场景——配合返回两个值的函数(如 map 取值、类型断言)非常顺手,还能避免变量泄漏到外层作用域被误用。
Go 没有三元运算符 x ? a : b,官方立场是三元表达式嵌套起来伤可读性,老老实实用 if-else。else if 链处理多分支时,条件从上往下短路执行,命中第一个为真的分支后其余不再判断,所以条件顺序要从严到宽排。简单的多值等值分支则该考虑下一章的 switch。
示例
基本的 if-else:
package main
import "fmt"
func main() {
age := 20
if age >= 18 {
fmt.Println("成年人")
} else {
fmt.Println("未成年")
}
score := 88
if score >= 90 {
fmt.Println("优秀")
} else if score >= 60 {
fmt.Println("及格")
} else {
fmt.Println("不及格")
}
}
带初始化语句的 if,变量只在分支内有效:
package main
import "fmt"
func grade(score int) string {
if score >= 90 {
return "优秀"
} else if score >= 60 {
return "及格"
}
return "不及格" // 走到这里一定是 60 以下,不用再写 else
}
func main() {
fmt.Println(grade(92), grade(70), grade(45))
if n := len([]int{1, 2, 3}); n > 2 {
fmt.Println("切片长度超过 2:", n)
}
// 这里访问不到 n,作用域仅限 if 内部
}
常见坑
- 给条件加圆括号:if (x > 0) 在 Go 里能编译但 gofmt 会帮你删掉括号,社区视为多余。反过来忘记大括号是直接编译错误。
- 左大括号换行:Go 的分号是词法器自动插入的,if cond 换行再写 { 会被解析成语句结束,编译报错。Go 强制 K&R 风格:左大括号永远在行尾。
- else if 链顺序颠倒:if score >= 60 写在 score >= 90 前面,90 分以上的人全被判成「及格」。范围条件从上到下必须由严到宽。
- 在条件里做赋值:if x = 5 是编译错误(Go 的条件必须是布尔表达式),这在客观上消灭了把 == 误写成 = 的经典 bug,但也要注意条件里不能顺手赋值。
- 滥用 if 初始化语句:初始化语句适合「临时算个值马上用」的场景,把复杂的多步逻辑塞进去会严重伤可读性,一行放不下就拆出来。
小结
if 条件无括号、大括号必须写、左大括号不换行;初始化语句让临时变量留在分支内;Go 没有三元运算符。下一节学习更适合多分支的 switch。