Go之路 - 5.go的流程控制

1. 条件语句

if-else 语句

基本用法
go 复制代码
// 基本的if语句
if condition {
    // 执行代码
}

// if-else语句
if condition {
    // condition为true时执行
} else {
    // condition为false时执行
}

// if-else if-else语句
if condition1 {
    // condition1为true时执行
} else if condition2 {
    // condition2为true时执行
} else {
    // 其他情况执行
}
实际示例
go 复制代码
package main

import "fmt"

func main() {
    // 示例1: 基本if
    age := 18
    if age >= 18 {
        fmt.Println("成年人")
    }

    // 示例2: if-else
    score := 85
    if score >= 60 {
        fmt.Println("及格")
    } else {
        fmt.Println("不及格")
    }

    // 示例3: if-else if-else
    grade := 88
    if grade >= 90 {
        fmt.Println("优秀")
    } else if grade >= 80 {
        fmt.Println("良好")
    } else if grade >= 60 {
        fmt.Println("及格")
    } else {
        fmt.Println("不及格")
    }
}
if的初始化语句

Go的if语句支持在执行条件判断前执行一个初始化语句:

go 复制代码
package main

import "fmt"

func main() {
    // 在if语句中初始化变量(作用域仅限于if语句块)
    if x := 10; x > 5 {
        fmt.Println("x大于5")
    }
    // 这里不能访问x,因为x的作用域仅限于if语句块内
    
    // 更实用的例子
    if num := getNumber(); num > 0 {
        fmt.Printf("%d是正数\n", num)
    }
    
    // 带else的初始化语句
    if value, err := calculate(); err != nil {
        fmt.Println("计算错误:", err)
    } else {
        fmt.Println("计算结果:", value)
    }
}

func getNumber() int {
    return 10
}

func calculate() (int, error) {
    return 42, nil
}

switch-case 语句

基本用法
go 复制代码
package main

import "fmt"

func main() {
    // 示例1: 基本switch
    day := 3
    switch day {
    case 1:
        fmt.Println("星期一")
    case 2:
        fmt.Println("星期二")
    case 3:
        fmt.Println("星期三")
    default:
        fmt.Println("其他天")
    }

    // 示例2: 多值匹配
    num := 5
    switch num {
    case 1, 3, 5, 7, 9:
        fmt.Println("奇数")
    case 2, 4, 6, 8, 10:
        fmt.Println("偶数")
    default:
        fmt.Println("不在1-10范围内")
    }

    // 示例3: 带表达式的switch(不需要break,自动跳出)
    score := 85
    switch {
    case score >= 90:
        fmt.Println("优秀")
    case score >= 80:
        fmt.Println("良好")
    case score >= 60:
        fmt.Println("及格")
    default:
        fmt.Println("不及格")
    }
}
switch的初始化语句
go 复制代码
package main

import (
    "fmt"
    "time"
)

func main() {
    // 在switch中初始化变量
    switch hour := time.Now().Hour(); {
    case hour < 12:
        fmt.Println("上午")
    case hour < 18:
        fmt.Println("下午")
    default:
        fmt.Println("晚上")
    }

    // 类型判断switch
    var x interface{} = 3.14
    
    switch v := x.(type) {
    case int:
        fmt.Printf("整数: %d\n", v)
    case float64:
        fmt.Printf("浮点数: %f\n", v)
    case string:
        fmt.Printf("字符串: %s\n", v)
    default:
        fmt.Printf("未知类型: %T\n", v)
    }
}
fallthrough关键字
go 复制代码
package main

import "fmt"

func main() {
    num := 2
    
    switch num {
    case 1:
        fmt.Println("是1")
        fallthrough // 继续执行下一个case
    case 2:
        fmt.Println("是2")
        fallthrough // 继续执行下一个case
    case 3:
        fmt.Println("是3")
        // 没有fallthrough,自动跳出
    default:
        fmt.Println("默认")
    }
    // 输出:
    // 是2
    // 是3
}

2. 循环语句

for循环

基本for循环
go 复制代码
package main

import "fmt"

func main() {
    // 示例1: 传统的for循环(类似C语言)
    for i := 0; i < 5; i++ {
        fmt.Printf("i = %d\n", i)
    }

    // 示例2: 类似while循环(只有条件)
    j := 0
    for j < 5 {
        fmt.Printf("j = %d\n", j)
        j++
    }

    // 示例3: 无限循环
    k := 0
    for {
        if k >= 3 {
            break // 跳出循环
        }
        fmt.Printf("k = %d\n", k)
        k++
    }
    
    // 示例4: 遍历数组/切片
    nums := []int{1, 2, 3, 4, 5}
    for index, value := range nums {
        fmt.Printf("索引: %d, 值: %d\n", index, value)
    }
    
    // 示例5: 遍历map
    m := map[string]int{"a": 1, "b": 2, "c": 3}
    for key, value := range m {
        fmt.Printf("键: %s, 值: %d\n", key, value)
    }
    
    // 示例6: 遍历字符串(字符)
    str := "Hello"
    for i, ch := range str {
        fmt.Printf("位置: %d, 字符: %c, Unicode码点: %U\n", i, ch, ch)
    }
}

循环控制语句

break和continue
go 复制代码
package main

import "fmt"

func main() {
    // break示例
    fmt.Println("break示例:")
    for i := 0; i < 10; i++ {
        if i == 5 {
            break // 跳出整个循环
        }
        fmt.Println(i)
    }
    
    // continue示例
    fmt.Println("\ncontinue示例:")
    for i := 0; i < 10; i++ {
        if i%2 == 0 {
            continue // 跳过本次循环,继续下一次
        }
        fmt.Println(i) // 只打印奇数
    }
    
    // 带标签的break(跳出多层循环)
    fmt.Println("\n带标签的break示例:")
outerLoop:
    for i := 0; i < 3; i++ {
        for j := 0; j < 3; j++ {
            fmt.Printf("i=%d, j=%d\n", i, j)
            if i == 1 && j == 1 {
                break outerLoop // 跳出外层循环
            }
        }
    }
    
    // 带标签的continue
    fmt.Println("\n带标签的continue示例:")
outer:
    for i := 0; i < 3; i++ {
        for j := 0; j < 3; j++ {
            if j == 1 {
                continue outer // 跳过外层循环的当前迭代
            }
            fmt.Printf("i=%d, j=%d\n", i, j)
        }
    }
}

3. goto语句

go 复制代码
package main

import "fmt"

func main() {
    // goto的基本使用
    var i int = 0
    
loop: // 标签声明
    if i < 5 {
        fmt.Println(i)
        i++
        goto loop // 跳转到标签处
    }
    
    // goto用于错误处理
    err := true
    if err {
        goto errorHandler
    }
    
    fmt.Println("正常流程")
    return
    
errorHandler:
    fmt.Println("错误处理流程")
    
    // 注意:goto不能跳过变量声明
    // 下面这样是错误的:
    // goto skip
    // var x int = 10
    // skip:
}

4. 特殊控制

defer语句

defer用于延迟执行,常用于资源清理:

go 复制代码
package main

import "fmt"

func main() {
    // defer的基本使用
    fmt.Println("开始")
    defer fmt.Println("延迟执行1") // 函数返回前执行
    defer fmt.Println("延迟执行2") // 多个defer,后进先出
    fmt.Println("结束")
    // 输出:
    // 开始
    // 结束
    // 延迟执行2
    // 延迟执行1
    
    // defer用于资源清理
    deferExample()
    
    // defer的参数在声明时即确定
    x := 10
    defer fmt.Println("defer时x的值:", x) // 输出10
    x = 20
    fmt.Println("修改后x的值:", x) // 输出20
}

func deferExample() {
    fmt.Println("打开文件")
    defer fmt.Println("关闭文件") // 确保文件会被关闭
    
    fmt.Println("处理文件")
    // 即使发生panic,defer也会执行
    
    // 多个defer的逆序执行
    defer fmt.Println("defer 1")
    defer fmt.Println("defer 2")
    defer fmt.Println("defer 3")
    // 输出顺序: defer 3, defer 2, defer 1, 关闭文件
}

panic和recover

用于错误处理和恢复:

go 复制代码
package main

import "fmt"

func main() {
    // panic示例
    fmt.Println("程序开始")
    
    // 使用recover捕获panic
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("从panic恢复:", r)
        }
    }()
    
    safeDivide(10, 2)
    safeDivide(10, 0) // 这里会panic,但会被recover捕获
    safeDivide(20, 5) // 这行不会执行
    
    fmt.Println("程序结束") // 这行不会执行,因为panic后程序在recover处继续执行
}

func safeDivide(a, b int) {
    if b == 0 {
        panic("除数不能为零") // 触发panic
    }
    result := a / b
    fmt.Printf("%d / %d = %d\n", a, b, result)
}

// 另一个recover示例
func example() {
    defer func() {
        fmt.Println("defer开始")
        if err := recover(); err != nil {
            fmt.Printf("捕获到panic: %v\n", err)
        }
        fmt.Println("defer结束")
    }()
    
    fmt.Println("函数开始")
    panic("发生错误") // 触发panic
    fmt.Println("这行不会执行") // panic后不会执行
}

这些是Go语言流程控制的核心概念。通过练习这些示例,你将能够熟练掌握Go的流程控制语句。

相关推荐
okseekw2 小时前
递归:不止是 “自己调用自己”,看完这篇秒懂
java·后端
sg_knight2 小时前
什么是设计模式?为什么 Python 也需要设计模式
开发语言·python·设计模式
脾气有点小暴2 小时前
UniApp实现刷新当前页面
开发语言·前端·javascript·vue.js·uni-app
是小胡嘛2 小时前
仿Muduo高并发服务器之Buffer模块
开发语言·c++·算法
温宇飞2 小时前
Drizzle ORM:类型安全的数据库开发
后端
SEO-狼术2 小时前
ASP.NET Zero v15.0.0 adds full .NET
后端·asp.net·.net
艾斯Felix2 小时前
SearXNG使用之引擎连接超时,响应成功但是空数据
后端
木木一直在哭泣2 小时前
我是怎么用 Redis 把 ERP→CRM 同步提速到“几秒钟”的
后端
零日失眠者2 小时前
【Python好用到哭的库】pandas-数据分析神器
后端·python·ai编程