switch后无表达式时判断各case布尔表达式的真假,首个为true者执行并跳出;case可列多值表示“或匹配”;fallthrough强制穿透至下一case但不验条件;type switch用于接口类型识别。

switch后面不写表达式,到底在判断什么?
它不是“没条件”,而是把每个 case 当作布尔表达式从上到下挨个求值,遇到第一个为 true 的就进去执行,然后自动跳出——本质是更清晰的 if-else if-else 链。
- 所有
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后跟多个值,逗号分隔是怎么回事?
这是 Go 对“或匹配”的原生支持,不是逻辑运算符,也不是区间写法。它只适用于带表达式的 switch(如 switch x),表示“匹配其中任意一个值”。
- 多个值之间只能用逗号,不能加空格以外的符号,比如
case 1 || 2:是非法语法,直接报错:invalid operation: || (mismatched types int and int) - 不支持区间(如
case 1..10:),也不能混用不同类型常量(比如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(不能用于无表达式 switch 或 type switch)。
-
fallthrough必须是case块中最后一条语句,后面不能跟其他代码 - 新代码不建议使用;它主要为兼容 C 风格移植代码存在,容易引发逻辑误解
- 如果想复用后续逻辑,更安全的做法是抽函数,而不是靠
fallthrough维持控制流 - 它不会继续向下穿透,除非每个中间
case都显式写fallthrough
示例(仅作说明,不推荐模仿):
s := "hello"
switch {
case s == "hello":
fmt.Println("hello")
fallthrough
case s != "world":
fmt.Println("world")
}
输出:hello 和 world,但注意第二行的 case 条件其实没被检查。
type switch 怎么安全识别接口类型?
当变量是 interface{} 或其他接口类型时,用 switch v := x.(type) 可在运行时识别具体底层类型,并绑定新变量 v 使用——这是 Go 唯一支持的类型断言批量处理方式。
- 每个
case后只能写类型名(如string、*MyStruct),不能写值或表达式 -
case nil专门匹配nil接口值,不是指变量未初始化,而是接口的动态值为nil - 不能混用普通值
case和type case,否则语法错误 -
default在这里不是兜底“其他类型”,而是兜底“其他所有类型”,包括未列出的类型
示例:
立即学习“go语言免费学习笔记(深入)”;
var x interface{} = "hello"
switch v := x.(type) {
case string:
fmt.Printf("字符串:%s\n", v)
case int:
fmt.Printf("整数:%d\n", v)
case nil:
fmt.Println("nil 值")
default:
fmt.Printf("未知类型:%T\n", v)
}
最容易被忽略的是:类型断言失败时不会 panic,而是直接走 default 或对应 case;但如果用了 v, ok := x.(string) 形式,就要自己判 ok。


















