switch 后无表达式时判断各 case 布尔表达式是否为 true,首个为 true 者执行并跳出;case 后多值是匹配列表而非逻辑或;fallthrough 无条件穿透至下一 case;type switch 专用于接口类型断言。

switch 后面不写表达式,到底在判断什么?
它不是“没条件”,而是把每个 case 当作布尔表达式从上到下挨个求值,遇到第一个为 true 的就进去执行,然后自动跳出——本质是更清晰的 if-else if-else 链。
- 所有
case必须是编译期可求值的布尔表达式,不能留空(比如case:会报错) - 顺序很重要:前面的
case匹配了,后面的哪怕也成立也不会执行 - 别在
case行里直接写赋值语句,比如case err := doSomething():—— Go 不允许,会编译失败;得提前声明或套一层if - 适合场景:分数段划分、权限组合判断、
nil或空值预检等无法用单值匹配的逻辑
示例:
立即学习 “go 语言免费学习笔记(深入)”;
score := 75 switch {case score >= 90: fmt.Println("A") case score >= 80: fmt.Println("B") case score >= 70: fmt.Println("C") default: fmt.Println("D") }
case 后跟多个值(如 case 1, 2, 3:)怎么理解?
这不是逻辑或(||),而是“匹配列表”——表示“等于其中任意一个值”,是 Go 对 C 风格 fallthrough 的替代设计,避免意外穿透。
- 逗号只能分隔同类型常量或字面量,不能加空格以外的运算符(
case 1, 2+1:合法,但case 1 || 2:直接报错) - 不支持区间写法(如
case 1..10:),需手动展开或改用无表达式switch - 不同包的
const(比如syscall.EINTR和os.ErrPermission)可能类型不一致,导致编译失败;这时要么统一转成int,要么改用无表达式switch+ 显式比较
示例:
立即学习 “go 语言免费学习笔记(深入)”;
day := 3 switch day {case 1, 2, 3: fmt.Println(" 工作日早段 ") case 4, 5: fmt.Println(" 工作日晚段 ") default: fmt.Println(" 周末或节假日 ") }
什么时候该用 fallthrough?又为什么建议少用?
fallthrough 是唯一能显式穿透到下一个 case 的方式,但它只穿透到 ** 紧邻的下一个 case 分支体 **,且不判断该 case 的条件是否满足——这和 C 完全不同。
- 必须是
case块最后一条语句,后面不能跟其他代码 - 仅限于带表达式的
switch(即switch x形式),不能用于无表达式或type switch - 新写的代码几乎不需要它;它存在的主要价值是兼容移植自 C 的旧逻辑
- 容易被误用:比如本意是“x == 1 时执行 one 和 two”,但如果写成
case 1: …… fallthrough case 2:,而x == 3,这个fallthrough根本不会触发——它的触发完全依赖前一个case是否命中
示例(合法但慎用):
s := "hello" switch {case s == "hello": fmt.Println("hello") fallthrough case s != "world": fmt.Println("world") } // 输出:hellonworld
switch v := x.(type) 专用于接口类型判断
这是运行时类型识别的安全方式,不是值匹配,不能和普通 case 混用——语法错误。
- 每个
case后只能写类型名(如string、int、*MyStruct),不能写值或表达式 -
case nil专门匹配nil接口值,不是类型 -
v的作用域仅限当前case分支,不能跨分支使用 - 不要试图在
type switch中混入值匹配(如case 42:),Go 会直接拒绝编译
示例:
立即学习 “go 语言免费学习笔记(深入)”;
var x interface{} = "hello" switch v := x.(type) {case string: fmt.Printf(" 字符串:%sn", v) case int: fmt.Printf(" 整数:%dn", v) case nil: fmt.Println("nil 值 ") default: fmt.Printf(" 未知类型:%Tn", v) }
真正容易被忽略的是:case 值的类型一致性、布尔表达式的求值时机、以及 fallthrough 的“无条件性”——它不看下一个 case 是否成立,只管往下跳。写错一行,逻辑就偏了。