Go 语言条件语句
条件语句是程序控制流的重要组成部分,允许程序根据不同条件执行不同的代码路径。Go 语言提供了 if 和 switch 两种主要的条件控制结构。
🔀 if 语句
基本 if 语句
go
package main
import "fmt"
func main() {
age := 18
// 基本 if 语句
if age >= 18 {
fmt.Println("你已经成年了")
}
// if-else 语句
score := 85
if score >= 90 {
fmt.Println("优秀")
} else {
fmt.Println("良好")
}
// 多条件判断
temperature := 25
if temperature < 0 {
fmt.Println("天气很冷")
} else if temperature < 20 {
fmt.Println("天气凉爽")
} else if temperature < 30 {
fmt.Println("天气温暖")
} else {
fmt.Println("天气炎热")
}
}if 语句的特殊语法
初始化语句
go
func main() {
// if 语句可以包含一个初始化语句
if num := 42; num > 0 {
fmt.Printf("%d 是正数\n", num)
}
// 注意:num 变量只在 if 块内有效
// 实际应用:处理函数返回值
if result, err := divide(10, 2); err != nil {
fmt.Printf("错误: %v\n", err)
} else {
fmt.Printf("结果: %.2f\n", result)
}
// 检查映射中的键
userAges := map[string]int{
"Alice": 25,
"Bob": 30,
}
if age, exists := userAges["Alice"]; exists {
fmt.Printf("Alice 的年龄是 %d\n", age)
} else {
fmt.Println("找不到 Alice 的年龄信息")
}
}
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, fmt.Errorf("除数不能为零")
}
return a / b, nil
}复杂条件判断
go
import "strings"
func main() {
// 逻辑运算符组合条件
username := "admin"
password := "123456"
isActive := true
if username == "admin" && password == "123456" && isActive {
fmt.Println("管理员登录成功")
} else {
fmt.Println("登录失败")
}
// 字符串条件判断
email := "user@example.com"
if strings.Contains(email, "@") && strings.Contains(email, ".") {
fmt.Println("邮箱格式看起来正确")
} else {
fmt.Println("邮箱格式不正确")
}
// 数值范围判断
score := 95
var grade string
if score >= 90 {
grade = "A"
} else if score >= 80 {
grade = "B"
} else if score >= 70 {
grade = "C"
} else if score >= 60 {
grade = "D"
} else {
grade = "F"
}
fmt.Printf("分数 %d 对应等级 %s\n", score, grade)
}🔄 switch 语句
基本 switch 语句
go
func main() {
// 基本 switch 语句
day := 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: // 多个值匹配同一个 case
fmt.Println("周末")
default:
fmt.Println("无效的日期")
}
// 字符串 switch
operation := "add"
switch operation {
case "add":
fmt.Println("执行加法运算")
case "subtract":
fmt.Println("执行减法运算")
case "multiply":
fmt.Println("执行乘法运算")
case "divide":
fmt.Println("执行除法运算")
default:
fmt.Println("未知运算")
}
}switch 语句的高级特性
带初始化的 switch
go
import "time"
func main() {
// switch 语句可以包含初始化语句
switch hour := time.Now().Hour(); {
case hour < 6:
fmt.Println("凌晨时光")
case hour < 12:
fmt.Println("上午时光")
case hour < 18:
fmt.Println("下午时光")
default:
fmt.Println("晚上时光")
}
// 在 switch 中调用函数
switch result := calculateGrade(85); result {
case "A":
fmt.Println("优秀成绩!")
case "B":
fmt.Println("良好成绩!")
case "C":
fmt.Println("及格成绩!")
default:
fmt.Println("需要努力!")
}
}
func calculateGrade(score int) string {
if score >= 90 {
return "A"
} else if score >= 80 {
return "B"
} else if score >= 70 {
return "C"
}
return "D"
}无表达式的 switch
go
func main() {
x := 15
// 无表达式的 switch(相当于 if-else 链)
switch {
case x < 0:
fmt.Println("x 是负数")
case x == 0:
fmt.Println("x 是零")
case x > 0 && x < 10:
fmt.Println("x 是个位正数")
case x >= 10 && x < 100:
fmt.Println("x 是两位正数")
default:
fmt.Println("x 是大于等于100的数")
}
// 复杂条件判断
temperature := 25
humidity := 60
switch {
case temperature > 30 && humidity > 70:
fmt.Println("又热又湿,不舒适")
case temperature > 30:
fmt.Println("天气炎热")
case temperature < 10:
fmt.Println("天气寒冷")
case humidity > 80:
fmt.Println("湿度很高")
default:
fmt.Println("天气适宜")
}
}fallthrough 关键字
go
func main() {
grade := "B"
// fallthrough 会继续执行下一个 case
switch grade {
case "A":
fmt.Println("优秀!")
fallthrough
case "B":
fmt.Println("良好!")
fallthrough
case "C":
fmt.Println("及格!")
// 没有 fallthrough,不会继续执行
case "D":
fmt.Println("不及格!")
default:
fmt.Println("无效等级")
}
// 输出:
// 良好!
// 及格!
// 注意:fallthrough 必须是 case 块的最后一条语句
processNumber := func(n int) {
switch n {
case 1:
fmt.Println("处理数字 1")
// 一些逻辑处理
fallthrough
case 2:
fmt.Println("数字 1 和 2 的通用处理")
case 3:
fmt.Println("处理数字 3")
}
}
processNumber(1)
fmt.Println("---")
processNumber(2)
}类型 switch
go
import "fmt"
func main() {
// 类型 switch 用于判断接口变量的实际类型
var x interface{} = 42
switch v := x.(type) {
case int:
fmt.Printf("x 是 int 类型,值为 %d\n", v)
case string:
fmt.Printf("x 是 string 类型,值为 %s\n", v)
case bool:
fmt.Printf("x 是 bool 类型,值为 %t\n", v)
case float64:
fmt.Printf("x 是 float64 类型,值为 %f\n", v)
default:
fmt.Printf("x 是未知类型 %T\n", v)
}
// 处理不同类型的数据
processValue := func(value interface{}) {
switch v := value.(type) {
case nil:
fmt.Println("值是 nil")
case int, int32, int64:
fmt.Printf("整数值: %v\n", v)
case float32, float64:
fmt.Printf("浮点数值: %v\n", v)
case string:
fmt.Printf("字符串值: %q\n", v)
case []int:
fmt.Printf("整数切片: %v\n", v)
default:
fmt.Printf("未处理的类型: %T\n", v)
}
}
processValue(42)
processValue(3.14)
processValue("hello")
processValue([]int{1, 2, 3})
processValue(true)
}🎯 实际应用示例
用户权限验证系统
go
import (
"fmt"
"strings"
)
// 用户角色
const (
RoleAdmin = "admin"
RoleUser = "user"
RoleGuest = "guest"
)
// 权限级别
const (
PermissionNone = 0
PermissionRead = 1
PermissionWrite = 2
PermissionDelete = 3
)
type User struct {
Username string
Role string
IsActive bool
Permission int
}
func main() {
users := []User{
{"admin", RoleAdmin, true, PermissionDelete},
{"john", RoleUser, true, PermissionWrite},
{"guest", RoleGuest, true, PermissionRead},
{"inactive", RoleUser, false, PermissionWrite},
}
for _, user := range users {
checkUserAccess(user, "delete_file")
fmt.Println("---")
}
}
func checkUserAccess(user User, action string) {
// 首先检查用户是否激活
if !user.IsActive {
fmt.Printf("用户 %s 账户未激活,拒绝访问\n", user.Username)
return
}
// 基于角色的访问控制
switch user.Role {
case RoleAdmin:
fmt.Printf("管理员 %s 拥有所有权限\n", user.Username)
performAction(action)
case RoleUser:
// 检查具体权限
if checkPermission(user.Permission, action) {
fmt.Printf("用户 %s 有权限执行 %s\n", user.Username, action)
performAction(action)
} else {
fmt.Printf("用户 %s 权限不足,无法执行 %s\n", user.Username, action)
}
case RoleGuest:
// 访客只能读取
if strings.HasPrefix(action, "read") {
fmt.Printf("访客 %s 可以执行只读操作 %s\n", user.Username, action)
performAction(action)
} else {
fmt.Printf("访客 %s 只能执行只读操作\n", user.Username)
}
default:
fmt.Printf("未知角色,拒绝访问\n")
}
}
func checkPermission(userPermission int, action string) bool {
switch action {
case "read_file", "view_data":
return userPermission >= PermissionRead
case "write_file", "update_data":
return userPermission >= PermissionWrite
case "delete_file", "delete_data":
return userPermission >= PermissionDelete
default:
return false
}
}
func performAction(action string) {
fmt.Printf(" -> 执行操作: %s\n", action)
}HTTP 状态码处理
go
import (
"fmt"
"net/http"
)
func main() {
// 模拟不同的 HTTP 状态码
statusCodes := []int{200, 201, 400, 401, 403, 404, 500, 502, 503}
for _, code := range statusCodes {
handleHTTPStatus(code)
}
}
func handleHTTPStatus(statusCode int) {
fmt.Printf("处理状态码 %d: ", statusCode)
switch {
case statusCode >= 200 && statusCode < 300:
// 2xx 成功状态码
switch statusCode {
case http.StatusOK:
fmt.Println("请求成功")
case http.StatusCreated:
fmt.Println("资源创建成功")
case http.StatusAccepted:
fmt.Println("请求已接受")
case http.StatusNoContent:
fmt.Println("请求成功,无内容返回")
default:
fmt.Println("其他成功状态")
}
case statusCode >= 300 && statusCode < 400:
// 3xx 重定向状态码
fmt.Println("需要重定向")
case statusCode >= 400 && statusCode < 500:
// 4xx 客户端错误
switch statusCode {
case http.StatusBadRequest:
fmt.Println("请求参数错误")
case http.StatusUnauthorized:
fmt.Println("需要身份验证")
case http.StatusForbidden:
fmt.Println("禁止访问")
case http.StatusNotFound:
fmt.Println("资源不存在")
case http.StatusMethodNotAllowed:
fmt.Println("请求方法不允许")
default:
fmt.Println("其他客户端错误")
}
case statusCode >= 500:
// 5xx 服务器错误
switch statusCode {
case http.StatusInternalServerError:
fmt.Println("服务器内部错误")
case http.StatusBadGateway:
fmt.Println("网关错误")
case http.StatusServiceUnavailable:
fmt.Println("服务不可用")
case http.StatusGatewayTimeout:
fmt.Println("网关超时")
default:
fmt.Println("其他服务器错误")
}
default:
fmt.Println("未知状态码")
}
}计算器应用
go
import (
"fmt"
"math"
)
func main() {
calculator := NewCalculator()
// 测试各种运算
testCases := []struct {
a, b float64
operation string
}{
{10, 5, "add"},
{10, 5, "subtract"},
{10, 5, "multiply"},
{10, 5, "divide"},
{10, 0, "divide"}, // 除零测试
{16, 0, "sqrt"},
{2, 8, "power"},
{10, 5, "unknown"}, // 未知操作
}
for _, test := range testCases {
result, err := calculator.Calculate(test.a, test.b, test.operation)
if err != nil {
fmt.Printf("%.1f %s %.1f = 错误: %v\n", test.a, test.operation, test.b, err)
} else {
if test.operation == "sqrt" {
fmt.Printf("%s(%.1f) = %.2f\n", test.operation, test.a, result)
} else {
fmt.Printf("%.1f %s %.1f = %.2f\n", test.a, test.operation, test.b, result)
}
}
}
}
type Calculator struct{}
func NewCalculator() *Calculator {
return &Calculator{}
}
func (c *Calculator) Calculate(a, b float64, operation string) (float64, error) {
switch operation {
case "add", "+":
return a + b, nil
case "subtract", "-":
return a - b, nil
case "multiply", "*":
return a * b, nil
case "divide", "/":
if b == 0 {
return 0, fmt.Errorf("除数不能为零")
}
return a / b, nil
case "power", "^":
return math.Pow(a, b), nil
case "sqrt":
if a < 0 {
return 0, fmt.Errorf("负数没有实数平方根")
}
return math.Sqrt(a), nil
case "mod", "%":
if b == 0 {
return 0, fmt.Errorf("模数不能为零")
}
return math.Mod(a, b), nil
default:
return 0, fmt.Errorf("不支持的运算: %s", operation)
}
}💡 最佳实践
条件语句的优化
go
func main() {
// ❌ 避免深层嵌套
badExample := func(user User) {
if user.IsActive {
if user.Role == "admin" {
if user.Permission >= PermissionWrite {
fmt.Println("允许访问")
} else {
fmt.Println("权限不足")
}
} else {
fmt.Println("非管理员")
}
} else {
fmt.Println("用户未激活")
}
}
// ✅ 使用早期返回
goodExample := func(user User) {
if !user.IsActive {
fmt.Println("用户未激活")
return
}
if user.Role != "admin" {
fmt.Println("非管理员")
return
}
if user.Permission < PermissionWrite {
fmt.Println("权限不足")
return
}
fmt.Println("允许访问")
}
testUser := User{"test", RoleAdmin, true, PermissionWrite}
fmt.Println("坏的示例:")
badExample(testUser)
fmt.Println("好的示例:")
goodExample(testUser)
}使用 switch 替代长 if-else 链
go
func main() {
// ❌ 长 if-else 链
gradeToGPA_Bad := func(grade string) float64 {
if grade == "A+" {
return 4.0
} else if grade == "A" {
return 4.0
} else if grade == "A-" {
return 3.7
} else if grade == "B+" {
return 3.3
} else if grade == "B" {
return 3.0
} else if grade == "B-" {
return 2.7
} else if grade == "C+" {
return 2.3
} else if grade == "C" {
return 2.0
} else if grade == "C-" {
return 1.7
} else if grade == "D" {
return 1.0
} else {
return 0.0
}
}
// ✅ 使用 switch
gradeToGPA_Good := func(grade string) float64 {
switch grade {
case "A+", "A":
return 4.0
case "A-":
return 3.7
case "B+":
return 3.3
case "B":
return 3.0
case "B-":
return 2.7
case "C+":
return 2.3
case "C":
return 2.0
case "C-":
return 1.7
case "D":
return 1.0
default:
return 0.0
}
}
grades := []string{"A", "B+", "C", "D", "F"}
fmt.Println("成绩转GPA:")
for _, grade := range grades {
gpa1 := gradeToGPA_Bad(grade)
gpa2 := gradeToGPA_Good(grade)
fmt.Printf("%s: %.1f (两种方法结果相同: %t)\n", grade, gpa1, gpa1 == gpa2)
}
}🎓 小结
本章我们全面学习了 Go 语言的条件语句:
- ✅ if 语句:基本语法、初始化语句、复杂条件判断
- ✅ switch 语句:基本用法、多值匹配、无表达式switch
- ✅ 特殊特性:fallthrough关键字、类型switch
- ✅ 实际应用:权限系统、状态处理、计算器应用
- ✅ 最佳实践:避免深层嵌套、优化条件链
条件语句是程序逻辑控制的核心,正确使用能让代码更清晰、更高效。
接下来,我们将学习 Go 语言循环语句,掌握程序的重复执行控制。
条件语句使用建议
- 优先使用早期返回避免深层嵌套
- 长 if-else 链可以考虑用 switch 替代
- 善用 switch 的初始化语句和类型判断
- 注意 fallthrough 的使用场景和限制