Go 语言条件语句
if / else、switch 的隐式 break、type switch、select。
Key PointsGo 的 `switch` 默认不贯穿,需要贯穿要显式写 `fallthrough`。
if
Go
score := 85
if score >= 90 {
fmt.Println("优秀")
} else if score >= 60 {
fmt.Println("及格")
} else {
fmt.Println("不及格")
}Output
及格No parentheses needed, but braces are mandatory — even for one line. That removes the classic C bug where a missing brace silently changes the logic.
if 带初始化语句
Go
if v, err := doSomething(); err == nil {
fmt.Println("成功", v)
} else {
fmt.Println("失败", err)
}
// v 和 err 出了 if 就没了The most common Go idiom: fetch and test together, scoping the variables to the branch so they cannot be misused outside.
switch
Go
day := 3
switch day {
case 1, 2, 3, 4, 5:
fmt.Println("工作日")
case 6, 7:
fmt.Println("周末")
default:
fmt.Println("非法")
}Output
工作日Go
// 无表达式的 switch:替代 if-else 链
score := 85
switch {
case score >= 90:
fmt.Println("A")
case score >= 80:
fmt.Println("B")
default:
fmt.Println("C")
}Output
Bfallthrough
Go
n := 1
switch n {
case 1:
fmt.Println("一")
fallthrough // 强制执行下一个 case
case 2:
fmt.Println("二")
case 3:
fmt.Println("三")
}Output
一
二fallthrough jumps unconditionally to the next case body, ignoring its condition, and must be the last statement. Real code rarely needs it — case 1, 2: is clearer.type switch
Go
func describe(x any) {
switch v := x.(type) {
case int:
fmt.Println("整数", v+1)
case string:
fmt.Println("字符串长度", len(v))
case []int:
fmt.Println("切片长度", len(v))
case nil:
fmt.Println("nil")
default:
fmt.Printf("其他类型 %T\n", v)
}
}
describe(42)
describe("hello")
describe([]int{1, 2})
describe(3.14)Output
整数 43
字符串长度 5
切片长度 2
其他类型 float64select
Go
ch1 := make(chan string)
ch2 := make(chan string)
go func() { ch1 <- "来自 ch1" }()
select {
case v := <-ch1:
fmt.Println(v)
case v := <-ch2:
fmt.Println(v)
case <-time.After(time.Second):
fmt.Println("超时")
}Output
来自 ch1select is the concurrent switch: whichever channel is ready first wins, and ties are broken randomly. Adding default makes it a non-blocking check.
if
Go
score := 85
if score >= 90 {
fmt.Println("优秀")
} else if score >= 60 {
fmt.Println("及格")
} else {
fmt.Println("不及格")
}Output
及格条件不需要括号,但花括号必须写——即使只有一行。这是强制的,避免「漏加大括号导致逻辑错位」这类 C 语言经典 bug。
if 带初始化语句
Go
if v, err := doSomething(); err == nil {
fmt.Println("成功", v)
} else {
fmt.Println("失败", err)
}
// v 和 err 出了 if 就没了这是 Go 里最常用的模式:把「取值」和「判断」写在一起,变量的作用域被限制在分支内,外面拿不到,也就不会被误用。
switch
Go
day := 3
switch day {
case 1, 2, 3, 4, 5:
fmt.Println("工作日")
case 6, 7:
fmt.Println("周末")
default:
fmt.Println("非法")
}Output
工作日Go
// 无表达式的 switch:替代 if-else 链
score := 85
switch {
case score >= 90:
fmt.Println("A")
case score >= 80:
fmt.Println("B")
default:
fmt.Println("C")
}Output
Bfallthrough
Go
n := 1
switch n {
case 1:
fmt.Println("一")
fallthrough // 强制执行下一个 case
case 2:
fmt.Println("二")
case 3:
fmt.Println("三")
}Output
一
二fallthrough 是无条件跳到下一个 case,不看条件,且必须是 case 块的最后一个语句。实际业务里几乎用不到,需要「合并条件」直接写 case 1, 2: 更清楚。type switch
Go
func describe(x any) {
switch v := x.(type) {
case int:
fmt.Println("整数", v+1)
case string:
fmt.Println("字符串长度", len(v))
case []int:
fmt.Println("切片长度", len(v))
case nil:
fmt.Println("nil")
default:
fmt.Printf("其他类型 %T\n", v)
}
}
describe(42)
describe("hello")
describe([]int{1, 2})
describe(3.14)Output
整数 43
字符串长度 5
切片长度 2
其他类型 float64select
Go
ch1 := make(chan string)
ch2 := make(chan string)
go func() { ch1 <- "来自 ch1" }()
select {
case v := <-ch1:
fmt.Println(v)
case v := <-ch2:
fmt.Println(v)
case <-time.After(time.Second):
fmt.Println("超时")
}Output
来自 ch1select 是并发版的 switch:哪个 channel 先就绪就走哪个分支;多个同时就绪时随机选一个。加 default 分支就变成非阻塞检查。