初始提交

This commit is contained in:
2025-08-24 01:01:26 +08:00
commit e51feb1296
35 changed files with 9348 additions and 0 deletions

View File

@@ -0,0 +1,600 @@
/*
02-switch.go - Go 语言 switch 语句详解
学习目标:
1. 掌握 switch 语句的基本用法
2. 理解 Go switch 的特殊特性
3. 学会使用 fallthrough 关键字
4. 了解类型 switch 的用法
5. 掌握无表达式 switch 的使用
知识点:
- switch 基本语法
- case 多值匹配
- fallthrough 关键字
- 类型 switch
- 无表达式 switch
- switch 中的变量声明
- 实际应用场景
*/
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
fmt.Println("=== Go 语言 switch 语句详解 ===\n")
// 演示基本 switch 语句
demonstrateBasicSwitch()
// 演示多值 case
demonstrateMultiValueCase()
// 演示 fallthrough
demonstrateFallthrough()
// 演示无表达式 switch
demonstrateExpressionlessSwitch()
// 演示类型 switch
demonstrateTypeSwitch()
// 演示 switch 中的变量声明
demonstrateSwitchWithDeclaration()
// 演示实际应用示例
demonstratePracticalExamples()
}
// demonstrateBasicSwitch 演示基本 switch 语句
func demonstrateBasicSwitch() {
fmt.Println("1. 基本 switch 语句:")
// 基本用法
day := 3
fmt.Printf(" 今天是星期 %d: ", day)
switch day {
case 1:
fmt.Printf("星期一\n")
case 2:
fmt.Printf("星期二\n")
case 3:
fmt.Printf("星期三\n")
case 4:
fmt.Printf("星期四\n")
case 5:
fmt.Printf("星期五\n")
case 6:
fmt.Printf("星期六\n")
case 7:
fmt.Printf("星期日\n")
default:
fmt.Printf("无效的日期\n")
}
// 字符串匹配
grade := "B"
fmt.Printf(" 成绩等级 %s: ", grade)
switch grade {
case "A":
fmt.Printf("优秀 (90-100分)\n")
case "B":
fmt.Printf("良好 (80-89分)\n")
case "C":
fmt.Printf("中等 (70-79分)\n")
case "D":
fmt.Printf("及格 (60-69分)\n")
case "F":
fmt.Printf("不及格 (0-59分)\n")
default:
fmt.Printf("无效等级\n")
}
// 字符匹配
char := 'a'
fmt.Printf(" 字符 '%c' 是: ", char)
switch char {
case 'a', 'e', 'i', 'o', 'u':
fmt.Printf("元音字母\n")
default:
fmt.Printf("辅音字母或其他字符\n")
}
// Go switch 的特点:自动 break
fmt.Printf(" Go switch 特点: 每个 case 自动 break不会继续执行下一个 case\n")
fmt.Println()
}
// demonstrateMultiValueCase 演示多值 case
func demonstrateMultiValueCase() {
fmt.Println("2. 多值 case:")
// 数字分组
number := 4
fmt.Printf(" 数字 %d 属于: ", number)
switch number {
case 1, 3, 5, 7, 9:
fmt.Printf("奇数\n")
case 2, 4, 6, 8, 10:
fmt.Printf("偶数\n")
case 0:
fmt.Printf("零\n")
default:
fmt.Printf("其他数字\n")
}
// 月份分组
month := 7
fmt.Printf(" %d月属于: ", month)
switch month {
case 12, 1, 2:
fmt.Printf("冬季\n")
case 3, 4, 5:
fmt.Printf("春季\n")
case 6, 7, 8:
fmt.Printf("夏季\n")
case 9, 10, 11:
fmt.Printf("秋季\n")
default:
fmt.Printf("无效月份\n")
}
// 工作日分组
weekday := "Saturday"
fmt.Printf(" %s 是: ", weekday)
switch weekday {
case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday":
fmt.Printf("工作日\n")
case "Saturday", "Sunday":
fmt.Printf("周末\n")
default:
fmt.Printf("无效日期\n")
}
// HTTP 状态码分组
statusCode := 404
fmt.Printf(" HTTP 状态码 %d: ", statusCode)
switch statusCode {
case 200, 201, 202, 204:
fmt.Printf("成功响应\n")
case 301, 302, 304:
fmt.Printf("重定向\n")
case 400, 401, 403, 404:
fmt.Printf("客户端错误\n")
case 500, 501, 502, 503:
fmt.Printf("服务器错误\n")
default:
fmt.Printf("其他状态码\n")
}
fmt.Println()
}
// demonstrateFallthrough 演示 fallthrough 关键字
func demonstrateFallthrough() {
fmt.Println("3. fallthrough 关键字:")
fmt.Printf(" fallthrough 让程序继续执行下一个 case\n")
score := 85
fmt.Printf(" 分数 %d 的评价:\n", score)
switch {
case score >= 90:
fmt.Printf(" 优秀\n")
fallthrough
case score >= 80:
fmt.Printf(" 良好\n")
fallthrough
case score >= 70:
fmt.Printf(" 中等\n")
fallthrough
case score >= 60:
fmt.Printf(" 及格\n")
default:
fmt.Printf(" 不及格\n")
}
// 另一个 fallthrough 示例
level := 2
fmt.Printf(" 用户等级 %d 的权限:\n", level)
switch level {
case 3:
fmt.Printf(" - 管理员权限\n")
fallthrough
case 2:
fmt.Printf(" - 编辑权限\n")
fallthrough
case 1:
fmt.Printf(" - 查看权限\n")
case 0:
fmt.Printf(" - 无权限\n")
}
// 注意事项
fmt.Printf(" 注意: fallthrough 只能在 case 的最后一行使用\n")
fmt.Printf(" 注意: fallthrough 会无条件执行下一个 case\n")
fmt.Println()
}
// demonstrateExpressionlessSwitch 演示无表达式 switch
func demonstrateExpressionlessSwitch() {
fmt.Println("4. 无表达式 switch:")
fmt.Printf(" 无表达式 switch 相当于 switch true可以替代长的 if-else if 链\n")
// 年龄分组
age := 25
fmt.Printf(" 年龄 %d 岁: ", age)
switch {
case age < 13:
fmt.Printf("儿童\n")
case age < 20:
fmt.Printf("青少年\n")
case age < 60:
fmt.Printf("成年人\n")
default:
fmt.Printf("老年人\n")
}
// 温度判断
temperature := 28
fmt.Printf(" 温度 %d°C: ", temperature)
switch {
case temperature < 0:
fmt.Printf("冰点以下\n")
case temperature < 10:
fmt.Printf("寒冷\n")
case temperature < 20:
fmt.Printf("凉爽\n")
case temperature < 30:
fmt.Printf("温暖\n")
default:
fmt.Printf("炎热\n")
}
// 复杂条件
hour := 14
isWeekend := false
fmt.Printf(" 时间 %d:00, 周末: %t - ", hour, isWeekend)
switch {
case hour < 6:
fmt.Printf("深夜时间\n")
case hour < 12 && !isWeekend:
fmt.Printf("工作上午\n")
case hour < 12 && isWeekend:
fmt.Printf("周末上午\n")
case hour < 18 && !isWeekend:
fmt.Printf("工作下午\n")
case hour < 18 && isWeekend:
fmt.Printf("周末下午\n")
case hour < 22:
fmt.Printf("晚上时间\n")
default:
fmt.Printf("夜晚时间\n")
}
// 数值范围判断
value := 75
fmt.Printf(" 数值 %d: ", value)
switch {
case value < 0:
fmt.Printf("负数\n")
case value == 0:
fmt.Printf("零\n")
case value <= 50:
fmt.Printf("小数值 (1-50)\n")
case value <= 100:
fmt.Printf("中等数值 (51-100)\n")
default:
fmt.Printf("大数值 (>100)\n")
}
fmt.Println()
}
// demonstrateTypeSwitch 演示类型 switch
func demonstrateTypeSwitch() {
fmt.Println("5. 类型 switch:")
fmt.Printf(" 类型 switch 用于判断接口变量的实际类型\n")
// 定义不同类型的变量
values := []interface{}{
42,
"hello",
3.14,
true,
[]int{1, 2, 3},
map[string]int{"a": 1},
nil,
}
for i, v := range values {
fmt.Printf(" 值 %d: %v - ", i+1, v)
switch t := v.(type) {
case nil:
fmt.Printf("nil 类型\n")
case bool:
fmt.Printf("布尔类型: %t\n", t)
case int:
fmt.Printf("整数类型: %d\n", t)
case string:
fmt.Printf("字符串类型: \"%s\" (长度: %d)\n", t, len(t))
case float64:
fmt.Printf("浮点类型: %.2f\n", t)
case []int:
fmt.Printf("整数切片: %v (长度: %d)\n", t, len(t))
case map[string]int:
fmt.Printf("字符串到整数的映射: %v\n", t)
default:
fmt.Printf("未知类型: %T\n", t)
}
}
// 类型 switch 的另一种用法
fmt.Printf(" 处理不同类型的数据:\n")
processValue(42)
processValue("Go语言")
processValue(3.14159)
processValue([]string{"a", "b", "c"})
fmt.Println()
}
// demonstrateSwitchWithDeclaration 演示 switch 中的变量声明
func demonstrateSwitchWithDeclaration() {
fmt.Println("6. switch 中的变量声明:")
// 在 switch 中声明变量
fmt.Printf(" 在 switch 中声明变量:\n")
switch num := rand.Intn(10); {
case num < 3:
fmt.Printf(" 随机数 %d < 3小数值\n", num)
case num < 7:
fmt.Printf(" 随机数 %d 在 3-6 之间,中等数值\n", num)
default:
fmt.Printf(" 随机数 %d >= 7大数值\n", num)
}
// 计算并判断
switch result := calculateGrade(85); result {
case "A":
fmt.Printf(" 成绩优秀: %s\n", result)
case "B":
fmt.Printf(" 成绩良好: %s\n", result)
case "C":
fmt.Printf(" 成绩中等: %s\n", result)
default:
fmt.Printf(" 成绩: %s\n", result)
}
// 字符串处理
switch length := len("Hello, World!"); {
case length < 5:
fmt.Printf(" 字符串长度 %d较短\n", length)
case length < 10:
fmt.Printf(" 字符串长度 %d中等\n", length)
default:
fmt.Printf(" 字符串长度 %d较长\n", length)
}
fmt.Println()
}
// demonstratePracticalExamples 演示实际应用示例
func demonstratePracticalExamples() {
fmt.Println("7. 实际应用示例:")
// 示例1: HTTP 请求处理
fmt.Printf(" 示例1 - HTTP 请求处理:\n")
method := "POST"
path := "/api/users"
switch method {
case "GET":
fmt.Printf(" 处理 GET 请求: 获取资源 %s\n", path)
case "POST":
fmt.Printf(" 处理 POST 请求: 创建资源 %s\n", path)
case "PUT":
fmt.Printf(" 处理 PUT 请求: 更新资源 %s\n", path)
case "DELETE":
fmt.Printf(" 处理 DELETE 请求: 删除资源 %s\n", path)
default:
fmt.Printf(" 不支持的 HTTP 方法: %s\n", method)
}
// 示例2: 文件扩展名处理
fmt.Printf(" 示例2 - 文件类型判断:\n")
filename := "document.pdf"
var fileType string
switch {
case hasExtension(filename, ".txt", ".md", ".doc", ".docx"):
fileType = "文档文件"
case hasExtension(filename, ".jpg", ".png", ".gif", ".bmp"):
fileType = "图片文件"
case hasExtension(filename, ".mp4", ".avi", ".mov", ".wmv"):
fileType = "视频文件"
case hasExtension(filename, ".mp3", ".wav", ".flac", ".aac"):
fileType = "音频文件"
case hasExtension(filename, ".pdf"):
fileType = "PDF文件"
case hasExtension(filename, ".zip", ".rar", ".7z", ".tar"):
fileType = "压缩文件"
default:
fileType = "未知文件类型"
}
fmt.Printf(" 文件 \"%s\" 是 %s\n", filename, fileType)
// 示例3: 游戏状态机
fmt.Printf(" 示例3 - 游戏状态处理:\n")
gameState := "playing"
playerHealth := 30
switch gameState {
case "menu":
fmt.Printf(" 显示主菜单\n")
case "playing":
fmt.Printf(" 游戏进行中\n")
switch {
case playerHealth <= 0:
fmt.Printf(" 玩家死亡,游戏结束\n")
case playerHealth < 20:
fmt.Printf(" 玩家生命值低 (%d),危险状态\n", playerHealth)
case playerHealth < 50:
fmt.Printf(" 玩家生命值中等 (%d),注意安全\n", playerHealth)
default:
fmt.Printf(" 玩家状态良好 (%d)\n", playerHealth)
}
case "paused":
fmt.Printf(" 游戏暂停\n")
case "gameover":
fmt.Printf(" 游戏结束\n")
default:
fmt.Printf(" 未知游戏状态: %s\n", gameState)
}
// 示例4: 错误码处理
fmt.Printf(" 示例4 - 错误码处理:\n")
errorCode := 1001
switch errorCode {
case 0:
fmt.Printf(" 操作成功\n")
case 1000, 1001, 1002:
fmt.Printf(" 用户相关错误 (错误码: %d)\n", errorCode)
switch errorCode {
case 1000:
fmt.Printf(" 用户不存在\n")
case 1001:
fmt.Printf(" 密码错误\n")
case 1002:
fmt.Printf(" 账户被锁定\n")
}
case 2000, 2001, 2002:
fmt.Printf(" 权限相关错误 (错误码: %d)\n", errorCode)
case 3000, 3001, 3002:
fmt.Printf(" 数据相关错误 (错误码: %d)\n", errorCode)
default:
fmt.Printf(" 未知错误 (错误码: %d)\n", errorCode)
}
// 示例5: 配置解析
fmt.Printf(" 示例5 - 配置解析:\n")
config := map[string]interface{}{
"debug": true,
"port": 8080,
"database": "mysql",
"timeout": 30.5,
}
for key, value := range config {
fmt.Printf(" 配置项 %s: ", key)
switch v := value.(type) {
case bool:
if v {
fmt.Printf("启用\n")
} else {
fmt.Printf("禁用\n")
}
case int:
fmt.Printf("数值 %d\n", v)
case float64:
fmt.Printf("浮点数 %.1f\n", v)
case string:
fmt.Printf("字符串 \"%s\"\n", v)
default:
fmt.Printf("未知类型 %T\n", v)
}
}
fmt.Println()
}
// 辅助函数
func processValue(v interface{}) {
switch val := v.(type) {
case int:
fmt.Printf(" 处理整数: %d平方: %d\n", val, val*val)
case string:
fmt.Printf(" 处理字符串: \"%s\",长度: %d\n", val, len(val))
case float64:
fmt.Printf(" 处理浮点数: %.3f,四舍五入: %.0f\n", val, val)
case []string:
fmt.Printf(" 处理字符串切片: %v元素个数: %d\n", val, len(val))
default:
fmt.Printf(" 无法处理的类型: %T\n", val)
}
}
func calculateGrade(score int) string {
switch {
case score >= 90:
return "A"
case score >= 80:
return "B"
case score >= 70:
return "C"
case score >= 60:
return "D"
default:
return "F"
}
}
func hasExtension(filename string, extensions ...string) bool {
for _, ext := range extensions {
if len(filename) >= len(ext) &&
filename[len(filename)-len(ext):] == ext {
return true
}
}
return false
}
func init() {
rand.Seed(time.Now().UnixNano())
}
/*
运行这个程序:
go run 02-switch.go
学习要点:
1. Go 的 switch 语句自动 break不需要显式写 break
2. case 可以包含多个值,用逗号分隔
3. fallthrough 关键字可以让程序继续执行下一个 case
4. 无表达式 switch 相当于 switch true可以替代长的 if-else if 链
5. 类型 switch 用于判断接口变量的实际类型
6. 可以在 switch 语句中声明变量
Go switch 的优势:
1. 比长的 if-else if 链更清晰
2. 自动 break 避免了忘记 break 的错误
3. 支持多值 case代码更简洁
4. 类型 switch 提供了强大的类型判断能力
5. 无表达式 switch 提供了灵活的条件判断
使用建议:
1. 当有多个固定值需要判断时,优先使用 switch
2. 当条件复杂时,使用无表达式 switch
3. 处理接口类型时,使用类型 switch
4. 谨慎使用 fallthrough确保逻辑正确
5. 合理使用 default 分支处理异常情况
常见应用场景:
1. 状态机实现
2. 错误码处理
3. 文件类型判断
4. HTTP 请求路由
5. 配置解析
6. 类型判断和处理
*/