一段判成绩的代码,case 90 里写了输出 A,跑出来 95 分打印了 A、B、C、D 四行。查了半天,少写一个 break。
switch 的匹配只决定从哪个 case 进去,进去之后会一直往下执行,直到遇到 break 或者 switch 结束。这个行为叫贯穿。
什么时候贯穿是有用的
几个值共用一段逻辑时可以故意不写 break,让空 case 一路落下去。这种写法清晰,读代码的人也知道是故意的。
危险的是 case 里有语句却忘了 break。别人分不清是漏了还是故意,改起来容易出事。
各语言不一样
- C、C++、Java、JS:默认贯穿,必须写 break。
- C#:不允许贯穿,case 里必须有 break 或 return,空的 case 可以连着写。
- Go:默认不贯穿,想贯穿要显式写 fallthrough。
- Python:3.10 之后有 match,默认不贯穿。
几类常见错误
在 case 里声明变量又没加大括号,编译报错,因为作用域跨到了别的 case。
switch 的表达式类型对不上,比如 C# 里 switch 一个字符串,case 写整数,编译过不去。
default 放最后不代表一定执行,它只在没有 case 匹配时才进。
枚举值不连续时,switch 比一串 if 清楚。但枚举后来加了新值,忘了补 case,程序会静默走 default,这种漏在测试里很难发现。
用字符串做 switch,各语言的比较规则不一样。有的区分大小写,有的不区分,跨语言移植时容易出岔子。
比 switch 省心的写法
分支超过五六个,或者每个分支都有一小段逻辑,用表驱动更清楚:把值和处理函数放进字典,取出来调用。加分支时只加一行,不动结构。
分支少、逻辑简单,switch 反而更直观。工具没有高下,看场景。
如果团队里总有人漏 break,就在规范里写死一条:case 里有语句就必须 break,故意贯穿的要加注释。