GO语言控制流程示例

GO语言控制流程示例

一、条件判断:if-else语句(深度解析)

1.1 基础结构与短声明
Go的if语句允许在条件中直接声明变量,这是其他语言不具备的特性。
语法:

if 变量, 错误 := 函数调用(); 条件表达式 {
    // 执行代码
}

示例:文件读取时的安全判断

package main
import (
    "fmt"
    "os"
)
func main() {
    if data, err := os.ReadFile("test.txt"); err == nil {
        fmt.Println("文件内容:", string(data))
    } else {
        fmt.Println("读取失败:", err)
    }
}

运行结果:

文件内容: Hello World!(当文件存在时)
或
读取失败: open test.txt: no such file or directory

关键点:

  • 变量作用域仅限当前if
  • 错误处理的最佳实践

1.2 嵌套条件与逻辑运算符
Go支持&&(与)、||(或)、!(非)三种逻辑运算符
实战案例:用户权限验证系统

package main
func main() {
    var (
        age     = 25
        isVIP   = true
        balance = 1500
    )
    
    if age >= 18 && (isVIP || balance >= 1000) {
        fmt.Println("权限通过")
    } else {
        fmt.Println("权限不足")
    }
}

运行结果:

权限通过(当前条件满足)

二、循环语句:for(全场景解析)

2.1 类C风格循环
语法结构:

for 初始化; 条件; 迭代 {
    // 循环体
}

进阶示例:素数生成器

package main
import "fmt"
func main() {
    primes := make([]int, 0)
    for num := 2; len(primes) < 10; num++ {
        isPrime := true
        for i := 2; i <= num/2; i++ {
            if num%i == 0 {
                isPrime = false
                break
            }
        }
        if isPrime {
            primes = append(primes, num)
        }
    }
    fmt.Println("前10个素数:", primes)
}

运行结果:

前10个素数: 

关键技巧:

  • 嵌套循环的应用
  • 素数判断算法优化

2.2 无限循环与通道通信
结合for{}和goroutine实现生产者-消费者模型
示例:并发日志处理系统

package main
import (
    "fmt"
    "sync"
    "time"
)
func main() {
    var (
        logs   = make(chan string, 100)
        wg     sync.WaitGroup
    )
    
    // 生产者
    wg.Add(1)
    go func() {
        defer wg.Done()
        for i := 0; i < 5; i++ {
            logs <- fmt.Sprintf("日志消息 %d", i)
            time.Sleep(time.Second)
        }
        close(logs)
    }()
    
    // 消费者
    wg.Add(1)
    go func() {
        defer wg.Done()
        for log := range logs {
            fmt.Println("处理:", log)
        }
    }()
    
    wg.Wait()
}

运行结果:

处理: 日志消息 0
处理: 日志消息 1
处理: 日志消息 2
处理: 日志消息 3
处理: 日志消息 4

核心技术:

  • 通道(channel)的使用
  • goroutine并发控制

2.3 for-range的深度应用

2.3.1 字符串遍历

package main
import "fmt"
func main() {
    s := "中English"
    for i, r := range s {
        fmt.Printf("索引%d: %c\n", i, r)
    }
}

运行结果:

索引0: 中
索引3: E
索引4: n
...

注意:中文字符占用3个字节,因此索引不连续

2.3.2 Map遍历优化

package main
import (
    "fmt"
    "sort"
)
func main() {
    scores := map[string]int{
        "Alice": 95,
        "Bob":   88,
        "Charlie": 76,
    }
    
    var keys []string
    for k := range scores {
        keys = append(keys, k)
    }
    sort.Strings(keys) // 按键排序
    
    for _, k := range keys {
        fmt.Printf("%s: %d\n", k, scores[k])
    }
}

运行结果:

Alice: 95
Bob: 88
Charlie: 76

技巧:通过临时切片实现有序遍历

三、流程控制:break/continue/fallthrough

3.1 多层循环跳出
使用带标签的break跳出多层循环
示例:二维数组查找

package main
import "fmt"
func main() {
    matrix := int{
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9},
    }
    
    search := 5
   外包:
    for i := 0; i < 3; i++ {
        for j := 0; j < 3; j++ {
            if matrix[i][j] == search {
                fmt.Printf("找到在位置%d-%d\n", i, j)
                break 外包 // 直接跳出外层循环
            }
        }
    }
}

运行结果:

找到在位置1-1

3.2 continue的深度应用
示例:过滤敏感词

package main
import "fmt"
func main() {
    text := "今天天气真好,我们去公园吧!"
    sensitive := map[rune]bool{'好': true, '园': true}
    
    var filtered string
    for _, r := range text {
        if sensitive[r] {
            continue // 跳过敏感字符
        }
        filtered += string(r)
    }
    fmt.Println(filtered)
}

运行结果:

今天天气,我们去吧!

3.3 fallthrough的危险用法
示例:多条件匹配陷阱

package main
import "fmt"
func main() {
    num := 5
    switch {
    case num < 0:
        fmt.Println("负数")
    case num < 10:
        fmt.Println("个位数")
        fallthrough // 错误!会导致后续条件被跳过
    case num < 100:
        fmt.Println("两位数")
    default:
        fmt.Println("其他")
    }
}

运行结果:

个位数
两位数

警告:使用fallthrough时需特别注意条件顺序

四、实战项目:简易计算器

结合所有控制语句开发交互式计算器

package main
import (
    "fmt"
    "os"
    "strconv"
    "strings"
)
func main() {
    for {
        fmt.Print("请输入表达式(输入q退出): ")
        var input string
        fmt.Scanln(&input)
        
        if strings lower(input) == "q" {
            fmt.Println("退出程序")
            os.Exit(0)
        }
        
        parts := strings.Split(input, " ")
        if len(parts) != 3 {
            fmt.Println("格式错误:应为 数字 运算符 数字")
            continue
        }
        
        num1, err1 := strconv.Atoi(parts)
        num2, err2 := strconv.Atoi(parts)
        if err1 != nil || err2 != nil {
            fmt.Println("请输入有效数字")
            continue
        }
        
        var result int
        switch parts {
        case "+":
            result = num1 + num2
        case "-":
            result = num1 - num2
        case "*":
            result = num1 * num2
        case "/":
            if num2 == 0 {
                fmt.Println("除数不能为0")
                continue
            }
            result = num1 / num2
        default:
            fmt.Println("不支持的运算符")
            continue
        }
        
        fmt.Printf("%s = %d\n", input, result)
    }
}

运行示例:

请输入表达式(输入q退出): 5 + 3
5 + 3 = 8
请输入表达式(输入q退出): 10 / 0
除数不能为0
请输入表达式(输入q退出): q
退出程序

包含技术点:

  • 无限循环
  • 条件判断
  • 错误处理
  • 字符串操作
  • 带标签的break

五、常见错误与调试技巧

  1. 循环变量作用域问题
for i := 0; i < 5; i++ {
    go func() {
        fmt.Println(i)
    }()
}

错误结果:输出5个5
修复方案:

for i := 0; i < 5; i++ {
    go func(j int) {
        fmt.Println(j)
    }(i)
}

  1. for-range遍历Map时的并发安全
m := map[int]string{1:"a", 2:"b"}
go func() {
    delete(m, 1)
}()
for k := range m {
    fmt.Println(k)
}

解决方案:先复制键到切片再遍历

六、性能优化建议

  1. 循环展开:对简单循环进行手动展开
  2. 避免重复计算:将循环内不变的计算移到外部
  3. 使用通道代替互斥锁:在并发场景中优先使用goroutine+channel

分享一张图片,未来加油!!布吉岛

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值