文章目录
- [Go 语言 switch 条件语句详解](#Go 语言 switch 条件语句详解)
-
- 一、前置准备
- [二、switch 核心语法(4种常用场景,重中之重)](#二、switch 核心语法(4种常用场景,重中之重))
-
- [1. 基础值匹配(最常用,单一值匹配)](#1. 基础值匹配(最常用,单一值匹配))
- [2. 多值匹配(case 后多个值)](#2. 多值匹配(case 后多个值))
- [3. 无表达式匹配(等价于多层 if else)](#3. 无表达式匹配(等价于多层 if else))
- [4. 类型匹配(type switch,Go 特色)](#4. 类型匹配(type switch,Go 特色))
- [三、Go 特色:fallthrough 关键字(穿透分支)](#三、Go 特色:fallthrough 关键字(穿透分支))
- [四、嵌套 switch 语句(进阶用法)](#四、嵌套 switch 语句(进阶用法))
- 五、综合实战案例(结合之前知识点)
- 六、新手常见错误(避坑指南)
- [七、switch 与 if else 的区别(新手必懂)](#七、switch 与 if else 的区别(新手必懂))
- 八、本篇总结
Go 语言 switch 条件语句详解
大家好~上一篇博客我们掌握了 for 循环语句,能让程序实现"重复执行"的逻辑;再之前我们学会了 if else 条件语句,能实现"分分支判断"。本篇我们学习另一种核心条件语句------switch 语句,它专门用于解决"多分支判断"场景,相比多层 if else 更简洁、可读性更强,是 Go 语言中高效的分支控制方式。
和之前一样,全程搭配可直接运行的代码示例,零基础也能轻松上手,重点讲解 Go 语言 switch 的独特用法(和其他语言有区别),学完就能用 switch 简化复杂的多分支逻辑,让代码更优雅、更易维护!
核心提示:Go 语言的 switch 相比 Java、C++ 更灵活,支持值匹配、类型匹配、无表达式匹配等多种场景,且默认自动终止分支,无需手动添加 break,这是新手最需要掌握的特色。
一、前置准备
继续使用我们的 GoStudy 项目,新建文件夹 switchdemo,创建 main\.go 文件,所有测试代码均在此文件中编写运行。
基础代码结构(复制即可):
go
package main
import "fmt"
func main() {
// 所有switch测试代码写在这里
}
核心说明:switch 的本质是"多分支匹配",当有多个条件需要判断时,用 switch 替代多层 if else,能让代码结构更清晰。比如"根据星期几输出对应问候语""根据成绩等级执行不同逻辑",用 switch 会比 if else if 更简洁高效[superscript:1]。
对比示例(直观感受 switch 的优势):
用 if else if 实现星期判断(繁琐):
go
var day int = 3
if day == 1 {
fmt.Println("周一")
} else if day == 2 {
fmt.Println("周二")
} else if day == 3 {
fmt.Println("周三")
} else if day == 4 {
fmt.Println("周四")
} else if day == 5 {
fmt.Println("周五")
} else if day == 6 || day == 7 {
fmt.Println("周末")
}
用 switch 实现星期判断(简洁):
go
var day int = 3
switch day {
case 1:
fmt.Println("周一")
case 2:
fmt.Println("周二")
case 3:
fmt.Println("周三")
case 4:
fmt.Println("周四")
case 5:
fmt.Println("周五")
case 6, 7: // 多个值用逗号分隔,满足任一即匹配
fmt.Println("周末")
}
二、switch 核心语法(4种常用场景,重中之重)
Go 语言的 switch 语法灵活多样,主要分为「基础值匹配」「多值匹配」「无表达式匹配」「类型匹配(type switch)」四种场景,我们逐一讲解,重点掌握语法细节和 Go 特色用法,避开新手常见坑。
1. 基础值匹配(最常用,单一值匹配)
场景:基于"变量或表达式的具体值"进行多分支判断,case 后跟单个具体值,适用于简单的多分支场景(如星期判断、月份判断)。
语法格式(必须严格遵循):
go
switch 变量/表达式 {
case 值1:
// 变量/表达式的值 == 值1 时,执行的代码
case 值2:
// 变量/表达式的值 == 值2 时,执行的代码
// 可添加多个case
default:
// 可选,所有case都不匹配时,执行的代码(类似if else的else)
}
关键注意点(Go 特色,必看):
-
switch 后的变量/表达式,类型必须和 case 后的值类型一致(比如变量是 int 型,case 后就不能是 string 型),否则编译报错。
-
执行完匹配的 case 分支后,自动终止整个 switch 语句,无需手动添加 break(和其他语言不同,这是 Go 的核心特色)[superscript:3]。
-
case 后的值必须是"常量"或"可编译时确定的值",不能是变量(比如 case a 会报错,除非 a 是常量)。
-
default 分支可选,位置不固定(可放在任意 case 之间),但通常放在最后,所有 case 都不匹配时才执行。
-
switch 后面的左大括号
\{,必须和 switch 及变量/表达式在同一行,否则编译报错(和 if、for 语法要求一致)。
示例代码:根据月份判断季节(基础值匹配)
go
package main
import "fmt"
func main() {
var month int
fmt.Print("请输入月份(1-12):")
fmt.Scan(&month)
// 基础值匹配:根据月份判断季节
switch month {
case 12:
fmt.Println("冬季")
case 1:
fmt.Println("冬季")
case 2:
fmt.Println("冬季")
case 3:
fmt.Println("春季")
case 4:
fmt.Println("春季")
case 5:
fmt.Println("春季")
case 6:
fmt.Println("夏季")
case 7:
fmt.Println("夏季")
case 8:
fmt.Println("夏季")
case 9:
fmt.Println("秋季")
case 10:
fmt.Println("秋季")
case 11:
fmt.Println("秋季")
default:
fmt.Println("输入的月份无效!")
}
}
运行结果示例:
Plain
请输入月份(1-12):3
春季
2. 多值匹配(case 后多个值)
场景:多个不同的值,对应相同的分支逻辑(比如"12、1、2月都属于冬季"),无需重复写多个 case,直接在 case 后用逗号分隔多个值即可,简化代码[superscript:4]。
语法格式:
go
switch 变量/表达式 {
case 值1, 值2, 值3: // 多个值用逗号分隔,满足任一值即匹配
// 执行的代码
case 值4, 值5:
// 执行的代码
default:
// 所有case不匹配时执行
}
关键说明:case 后的多个值,类型必须和 switch 后的变量/表达式类型一致,否则编译报错;只要匹配其中一个值,就会执行该 case 的代码,执行完自动终止 switch。
示例代码:简化月份判断季节(多值匹配)
go
package main
import "fmt"
func main() {
var month int
fmt.Print("请输入月份(1-12):")
fmt.Scan(&month)
// 多值匹配:多个月份对应同一个季节,简化代码
switch month {
case 12, 1, 2: // 12、1、2月都是冬季
fmt.Println("冬季")
case 3, 4, 5: // 3、4、5月都是春季
fmt.Println("春季")
case 6, 7, 8: // 6、7、8月都是夏季
fmt.Println("夏季")
case 9, 10, 11: // 9、10、11月都是秋季
fmt.Println("秋季")
default:
fmt.Println("输入的月份无效!")
}
}
运行结果:和基础值匹配一致,但代码更简洁,避免了重复逻辑。
小贴士:多值匹配是 Go 开关语句的常用优化方式,当多个值对应同一逻辑时,优先使用这种写法,提升代码可读性和简洁度[superscript:2]。
3. 无表达式匹配(等价于多层 if else)
场景:没有明确的"变量/表达式",需要根据多个自定义布尔条件进行判断,此时可以省略 switch 后的表达式,等价于多层 if else if 链,适用于复杂的多条件分支场景[superscript:1]。
核心特点:省略表达式后,switch 等价于 switch true,每个 case 后跟一个布尔条件表达式,满足条件(结果为 true)就执行对应的分支[superscript:3]。
语法格式:
go
switch { // 省略表达式,等价于 switch true
case 布尔条件1:
// 条件1为true时,执行的代码
case 布尔条件2:
// 条件2为true时,执行的代码
// 可添加多个case
default:
// 所有条件都为false时,执行的代码
}
关键注意点:这种写法和多层 if else if 逻辑完全一致,但语法更简洁,可读性更强,尤其适合条件较多的场景[superscript:5]。
示例代码:判断数字的正负性(无表达式匹配)
go
package main
import "fmt"
func main() {
var num int
fmt.Print("请输入一个整数:")
fmt.Scan(&num)
// 无表达式switch,等价于多层if else if
switch {
case num > 0 && num%2 == 0:
fmt.Printf("%d 是正偶数\n", num)
case num > 0 && num%2 != 0:
fmt.Printf("%d 是正奇数\n", num)
case num < 0:
fmt.Printf("%d 是负数\n", num)
default:
fmt.Printf("%d 是0\n", num)
}
}
运行结果示例:
Plain
请输入一个整数:15
15 是正奇数
4. 类型匹配(type switch,Go 特色)
场景:判断"空接口变量(interface{})"的具体类型,通过 switch v := x\.\(type\) 语法,获取空接口 x 的动态类型,是 Go 语言中类型断言的常用方式之一[superscript:1]。
核心用途:空接口可以存储任意类型的值,当我们不知道变量的具体类型时,用 type switch 可以快速判断其类型,进而执行对应的逻辑(后续学习接口时会高频用到)。
语法格式:
go
switch v := 空接口变量.(type) { // 固定格式:变量.(type)
case 类型1: // 比如 int、string、bool 等
// v 自动转换为类型1,可直接使用
// 执行的代码
case 类型2:
// v 自动转换为类型2,可直接使用
// 执行的代码
default:
// 变量类型不匹配任何case时,执行的代码
}
关键注意点:
-
switch 后必须是
变量\.\(type\)格式,变量通常为 interface{} 类型(空接口)[superscript:4]。 -
每个 case 后跟具体的类型(如 int、string、bool 等),不能跟值。
-
匹配成功后,变量 v 会自动转换为对应的 case 类型,可直接使用(无需手动类型转换)。
示例代码:判断变量的具体类型(type switch)
go
package main
import "fmt"
// 定义函数,接收空接口参数(可接收任意类型)
func checkType(x interface{}) {
// 类型匹配:判断x的具体类型
switch v := x.(type) {
case int:
fmt.Printf("类型:int,值:%d\n", v)
case string:
fmt.Printf("类型:string,值:%s\n", v)
case bool:
fmt.Printf("类型:bool,值:%t\n", v)
case float64:
fmt.Printf("类型:float64,值:%.2f\n", v)
default:
fmt.Printf("未知类型:%T\n", v) // %T 查看变量类型
}
}
func main() {
checkType(100) // int类型
checkType("Go语言") // string类型
checkType(true) // bool类型
checkType(3.14) // float64类型
checkType([]int{1,2,3}) // 切片类型(未知类型)
}
运行结果:
Plain
类型:int,值:100
类型:string,值:Go语言
类型:bool,值:true
类型:float64,值:3.14
未知类型:[]int
三、Go 特色:fallthrough 关键字(穿透分支)
我们之前说过,Go 的 switch 执行完匹配的 case 后,会自动终止整个 switch,无需手动 break。但有些场景下,我们需要"执行完当前 case 后,继续执行下一个 case",这就需要用到 fallthrough关键字[superscript:1]。
语法格式:
go
switch 变量/表达式 {
case 值1:
// 执行的代码
fallthrough // 穿透到下一个case,不判断条件,直接执行
case 值2:
// 无论值是否匹配,都会执行(因为fallthrough)
// 可继续添加fallthrough,继续穿透
default:
// 执行的代码
}
关键注意点:
-
fallthrough必须放在 case 分支的最后一行,不能放在中间(否则编译报错)[superscript:3]。 -
fallthrough只会穿透到"下一个 case",不会跳过中间的 case,且不重新判断下一个 case 的条件。 -
不建议频繁使用 fallthrough,容易导致逻辑混乱,仅在特定场景下使用(如需要连续执行多个分支)。
示例代码:fallthrough 穿透示例
go
package main
import "fmt"
func main() {
var num int = 2
switch num {
case 1:
fmt.Println("匹配到1")
fallthrough
case 2:
fmt.Println("匹配到2")
fallthrough // 穿透到下一个case
case 3:
fmt.Println("穿透到3(无需匹配)")
// 没有fallthrough,终止switch
case 4:
fmt.Println("不会执行")
default:
fmt.Println("默认分支")
}
}
运行结果:
Plain
匹配到2
穿透到3(无需匹配)
重点提醒:fallthrough 仅作用于当前 case 的下一个 case,且不会判断下一个 case 的条件,直接执行,使用时务必谨慎,避免逻辑出错。
四、嵌套 switch 语句(进阶用法)
场景:在一个 switch 分支内部,再嵌套另一个完整的 switch 语句,用于处理"多层多分支"的复杂逻辑(比如"先判断季节,再判断月份是否是节假日")[superscript:4]。
语法格式(简化):
go
switch 外层条件 {
case 外层值1:
// 外层匹配成功,执行此处
switch 内层条件 {
case 内层值1:
// 内层匹配成功,执行此处
case 内层值2:
// 内层匹配成功,执行此处
}
case 外层值2:
// 外层匹配成功,执行此处
default:
// 外层所有case不匹配时执行
}
关键注意点:
-
嵌套层级建议不超过 2 层,否则代码可读性变差,容易出错。
-
外层 switch 和内层 switch 是相互独立的,内层的 break、fallthrough 仅作用于内层 switch,不影响外层。
-
嵌套 switch 的语法规范和普通 switch 一致(大括号位置、类型匹配等)。
示例代码:嵌套 switch 示例(判断季节+节假日)
go
package main
import "fmt"
func main() {
var month int
fmt.Print("请输入月份(1-12):")
fmt.Scan(&month)
// 外层switch:判断季节
switch month {
case 12, 1, 2:
fmt.Println("冬季")
// 内层switch:判断冬季是否有节假日
switch month {
case 1:
fmt.Println("包含节假日:元旦")
case 12:
fmt.Println("包含节假日:圣诞节、元旦")
case 2:
fmt.Println("包含节假日:春节")
}
case 3, 4, 5:
fmt.Println("春季")
switch month {
case 5:
fmt.Println("包含节假日:劳动节")
default:
fmt.Println("无重大节假日")
}
case 6, 7, 8:
fmt.Println("夏季")
switch month {
case 6:
fmt.Println("包含节假日:端午节")
default:
fmt.Println("无重大节假日")
}
case 9, 10, 11:
fmt.Println("秋季")
switch month {
case 10:
fmt.Println("包含节假日:国庆节")
default:
fmt.Println("无重大节假日")
}
default:
fmt.Println("输入的月份无效!")
}
}
运行结果示例:
Plain
请输入月份(1-12):1
冬季
包含节假日:元旦
五、综合实战案例(结合之前知识点)
结合「控制台输入」「if else」「for 循环」「switch」,实现一个"学生成绩评级+根据评级给出升学建议"的完整程序,巩固本篇所有知识点,同时衔接前文内容。
需求:
-
接收用户输入的学生人数;
-
循环录入每个学生的语文、数学、英语三科成绩;
-
计算三科平均分,用 switch 进行成绩分级(优秀≥90、良好80-89、及格60-79、不及格<60);
-
根据评级,用 switch 给出升学建议(优秀:冲刺重点院校、良好:稳进本科、及格:争取本科、不及格:复读/职业院校);
-
输出每个学生的成绩、平均分、评级和升学建议。
完整代码:
go
package main
import "fmt"
func main() {
var studentNum int
var chinese, math, english int
var average float64
var level string
var suggestion string
// 1. 接收学生人数
fmt.Print("请输入学生人数:")
fmt.Scan(&studentNum)
// 2. 循环录入每个学生的成绩(for循环)
for i := 1; i <= studentNum; i++ {
fmt.Printf("------------------- 第%d个学生 -------------------\n", i)
fmt.Print("请输入语文、数学、英语成绩(空格分隔):")
fmt.Scan(&chinese, &math, &english)
// 3. 计算平均分
average = (chinese + math + english) / 3.0
// 4. switch 成绩分级(无表达式匹配)
switch {
case average >= 90:
level = "优秀"
case average >= 80:
level = "良好"
case average >= 60:
level = "及格"
default:
level = "不及格"
}
// 5. switch 根据评级给出升学建议(基础值匹配)
switch level {
case "优秀":
suggestion = "冲刺重点院校,保持优势!"
case "良好":
suggestion = "稳进本科,查漏补缺,争取提升!"
case "及格":
suggestion = "争取本科,加强薄弱科目,奋起直追!"
case "不及格":
suggestion = "建议复读或选择职业院校,找准发展方向!"
}
// 6. 输出结果
fmt.Printf("语文:%d 分,数学:%d 分,英语:%d 分\n", chinese, math, english)
fmt.Printf("平均分:%.1f 分,评级:%s\n", average, level)
fmt.Printf("升学建议:%s\n", suggestion)
}
fmt.Println("------------------- 录入完成 -------------------")
}
运行结果示例:
Plain
请输入学生人数:2
------------------- 第1个学生 -------------------
请输入语文、数学、英语成绩(空格分隔):92 95 88
语文:92 分,数学:95 分,英语:88 分
平均分:91.7 分,评级:优秀
升学建议:冲刺重点院校,保持优势!
------------------- 第2个学生 -------------------
请输入语文、数学、英语成绩(空格分隔):75 68 72
语文:75 分,数学:68 分,英语:72 分
平均分:71.7 分,评级:及格
升学建议:争取本科,加强薄弱科目,奋起直追!
------------------- 录入完成 -------------------
六、新手常见错误(避坑指南)
-
大括号位置错误 :switch 后面的左大括号
\{没有和 switch 在同一行,导致编译报错(和 if、for 语法要求一致)。错误示例:
switch month \{ // 错误:\{ 不能换行 case 1: fmt\.Println\(\&\#34;冬季\&\#34;\) \} -
case 后用变量 :case 后必须是常量或可编译时确定的值,不能用变量(比如
case a,a 是变量,会报错)[superscript:5]。 -
类型不匹配:switch 后的变量/表达式类型,和 case 后的值类型不一致(比如 switch 是 int 型,case 是 string 型),编译报错。
-
多余添加 break:误以为需要手动添加 break 终止分支,其实 Go 会自动终止,添加 break 也能运行,但属于多余操作,不符合 Go 代码规范[superscript:3]。
-
fallthrough 位置错误:fallthrough 没有放在 case 分支的最后一行,导致编译报错;或滥用 fallthrough,导致逻辑混乱。
-
type switch 语法错误 :类型匹配时,写成
switch x\.type或switch x\.\(int\),正确写法是switch v := x\.\(type\)[superscript:1]。 -
无表达式 switch 写多余条件 :无表达式 switch 等价于 switch true,case 后必须是布尔条件,不能写具体值(比如
case 1会报错)。 -
case 重复:多个 case 后跟相同的值,导致编译报错(case 值必须唯一)。
七、switch 与 if else 的区别(新手必懂)
很多新手会混淆 switch 和 if else,其实两者适用场景不同,合理选择能让代码更优雅,具体区别如下[superscript:5]:
| 对比维度 | switch 语句 | if else 语句 |
|---|---|---|
| 适用场景 | 多分支判断,且分支条件是"值匹配"或"类型匹配" | 单分支、双分支,或复杂的布尔条件判断 |
| 代码简洁度 | 多分支时更简洁,可读性更强 | 多分支时(if else if)繁琐,可读性差 |
| 性能优化 | case 为整型常量时,编译器可能优化为跳转表,性能更优 | 无特殊优化,多分支时需逐个判断 |
| 灵活性 | 支持值匹配、类型匹配、无表达式匹配,灵活度高 | 仅支持布尔条件判断,灵活度一般 |
总结:当需要判断"一个变量/表达式的多个可能值"时,优先用 switch;当需要判断"复杂的布尔条件"(比如多个条件组合)时,用 if else 更合适[superscript:2]。
八、本篇总结
-
核心作用:switch 用于多分支判断,替代多层 if else,让代码更简洁、可读性更强,支持多种匹配场景[superscript:1]。
-
四种常用场景:
-
基础值匹配:switch 后跟变量/表达式,case 后跟单一值;
-
多值匹配:case 后用逗号分隔多个值,满足任一即匹配;
-
无表达式匹配:省略 switch 后的表达式,等价于多层 if else if;
-
类型匹配(type switch):判断空接口变量的具体类型,Go 特色用法。
-
-
Go 特色:
-
执行完匹配的 case 后,自动终止 switch,无需手动添加 break;
-
支持 fallthrough 关键字,实现分支穿透;
-
type switch 用于类型判断,适配空接口的灵活特性。
-
-
进阶用法:嵌套 switch 用于复杂的多层多分支逻辑,嵌套不超过 2 层。
-
实战技巧:结合 for 循环、if else,实现"输入→循环处理→多分支判断→输出"的完整逻辑;根据场景合理选择 switch 和 if else。
本篇的 switch 语句是 Go 语言流程控制的重要组成部分,掌握后能大幅提升代码的简洁度和可维护性。
(注:文档部分内容可能由 AI 生成)