流程控制

流程控制是编程语言的核心概念,用于控制程序的执行顺序。Go 语言提供了简洁而强大的流程控制语句。本章将详细介绍 Go 的流程控制。

流程控制概述

Go 语言的流程控制包括:

类型语句说明
条件判断if, if-else, if-else if根据条件执行不同代码
循环for重复执行代码
选择switch多条件选择
跳转break, continue, goto改变执行流程

注意:Go 没有 whiledo-while 循环,统一使用 for 实现。

if 条件判断

基本 if 语句

if 条件 {
    // 条件为 true 时执行
}

示例:

package main

import "fmt"

func main() {
    age := 18

    if age >= 18 {
        fmt.Println("已成年")
    }
}

if-else 语句

if 条件 {
    // 条件为 true 时执行
} else {
    // 条件为 false 时执行
}

示例:

package main

import "fmt"

func main() {
    age := 16

    if age >= 18 {
        fmt.Println("已成年")
    } else {
        fmt.Println("未成年")
    }
}

if-else if-else 语句

if 条件1 {
    // 条件1 为 true 时执行
} else if 条件2 {
    // 条件2 为 true 时执行
} else {
    // 所有条件都为 false 时执行
}

示例:

package main

import "fmt"

func main() {
    score := 85

    if score >= 90 {
        fmt.Println("优秀")
    } else if score >= 80 {
        fmt.Println("良好")
    } else if score >= 60 {
        fmt.Println("及格")
    } else {
        fmt.Println("不及格")
    }
}

输出:

良好

if 语句中声明变量

可以在 if 语句中声明变量,变量的作用域限于 if 语句块:

package main

import "fmt"

func main() {
    if score := 85; score >= 60 {
        fmt.Printf("及格,分数: %d\n", score)
    } else {
        fmt.Printf("不及格,分数: %d\n", score)
    }
}

注意事项

1. 条件不需要括号

if age >= 18 {
    fmt.Println("已成年")
}

2. 大括号必须有,且左大括号不能换行

if age >= 18
{
    fmt.Println("已成年")
}

正确写法:

if age >= 18 {
    fmt.Println("已成年")
}

for 循环

Go 只有 for 一种循环关键字,但可以模拟多种循环形式。

基本 for 循环

for 初始化; 条件; 后置语句 {
    // 循环体
}

示例:

package main

import "fmt"

func main() {
    for i := 0; i < 5; i++ {
        fmt.Printf("i = %d\n", i)
    }
}

输出:

i = 0
i = 1
i = 2
i = 3
i = 4

执行流程:

初始化 → 条件判断 → 循环体 → 后置语句 → 条件判断 → ...

模拟 while 循环

省略初始化和后置语句:

for 条件 {
    // 循环体
}

示例:

package main

import "fmt"

func main() {
    i := 0
    for i < 5 {
        fmt.Printf("i = %d\n", i)
        i++
    }
}

无限循环

省略所有条件:

for {
    // 循环体
}

示例:

package main

import "fmt"

func main() {
    i := 0
    for {
        fmt.Printf("i = %d\n", i)
        i++
        if i >= 5 {
            break
        }
    }
}

for-range 循环

用于遍历数组、切片、字符串、map 等:

遍历字符串:

package main

import "fmt"

func main() {
    s := "Hello, 世界"

    fmt.Println("遍历字节:")
    for i := 0; i < len(s); i++ {
        fmt.Printf("索引 %d: %c\n", i, s[i])
    }

    fmt.Println("\n遍历字符:")
    for i, r := range s {
        fmt.Printf("索引 %d: %c\n", i, r)
    }
}

遍历切片:

package main

import "fmt"

func main() {
    nums := []int{10, 20, 30, 40, 50}

    for index, value := range nums {
        fmt.Printf("索引: %d, 值: %d\n", index, value)
    }

    for _, value := range nums {
        fmt.Printf("值: %d\n", value)
    }

    for index := range nums {
        fmt.Printf("索引: %d\n", index)
    }
}

遍历 map:

package main

import "fmt"

func main() {
    scores := map[string]int{
        "张三": 85,
        "李四": 92,
        "王五": 78,
    }

    for name, score := range scores {
        fmt.Printf("%s: %d 分\n", name, score)
    }
}

嵌套循环

package main

import "fmt"

func main() {
    for i := 1; i <= 9; i++ {
        for j := 1; j <= i; j++ {
            fmt.Printf("%d * %d = %d\t", j, i, i*j)
        }
        fmt.Println()
    }
}

输出:

1 * 1 = 1
1 * 2 = 2    2 * 2 = 4
1 * 3 = 3    2 * 3 = 6    3 * 3 = 9
...

switch 语句

switch 用于多条件选择,比多个 if-else 更清晰。

基本 switch

switch 表达式 {
case1:
    // 执行代码
case2:
    // 执行代码
default:
    // 默认执行代码
}

示例:

package main

import "fmt"

func main() {
    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:
        fmt.Println("星期六")
    case 7:
        fmt.Println("星期日")
    default:
        fmt.Println("无效的日期")
    }
}

输出:

星期三

多值匹配

一个 case 可以匹配多个值:

package main

import "fmt"

func main() {
    day := 6

    switch day {
    case 1, 2, 3, 4, 5:
        fmt.Println("工作日")
    case 6, 7:
        fmt.Println("周末")
    default:
        fmt.Println("无效的日期")
    }
}

输出:

周末

无表达式 switch

switch 不加表达式时,相当于 if-else:

package main

import "fmt"

func main() {
    score := 85

    switch {
    case score >= 90:
        fmt.Println("优秀")
    case score >= 80:
        fmt.Println("良好")
    case score >= 60:
        fmt.Println("及格")
    default:
        fmt.Println("不及格")
    }
}

输出:

良好

fallthrough 穿透

默认情况下,case 执行完后会自动跳出。使用 fallthrough 可以继续执行下一个 case:

package main

import "fmt"

func main() {
    num := 2

    switch num {
    case 1:
        fmt.Println("1")
        fallthrough
    case 2:
        fmt.Println("2")
        fallthrough
    case 3:
        fmt.Println("3")
    default:
        fmt.Println("default")
    }
}

输出:

2
3

switch 中声明变量

package main

import "fmt"

func main() {
    switch num := 10; {
    case num < 0:
        fmt.Println("负数")
    case num == 0:
        fmt.Println("零")
    default:
        fmt.Println("正数")
    }
}

break 和 continue

break

break 用于跳出循环:

package main

import "fmt"

func main() {
    for i := 0; i < 10; i++ {
        if i == 5 {
            fmt.Println("跳出循环")
            break
        }
        fmt.Printf("i = %d\n", i)
    }
}

输出:

i = 0
i = 1
i = 2
i = 3
i = 4
跳出循环

continue

continue 用于跳过本次循环,继续下一次:

package main

import "fmt"

func main() {
    for i := 0; i < 10; i++ {
        if i%2 == 0 {
            continue
        }
        fmt.Printf("i = %d\n", i)
    }
}

输出:

i = 1
i = 3
i = 5
i = 7
i = 9

标签跳转

使用标签可以跳出多层循环:

package main

import "fmt"

func main() {
outer:
    for i := 0; i < 3; i++ {
        for j := 0; j < 3; j++ {
            if i == 1 && j == 1 {
                fmt.Println("跳出外层循环")
                break outer
            }
            fmt.Printf("i = %d, j = %d\n", i, j)
        }
    }
}

输出:

i = 0, j = 0
i = 0, j = 1
i = 0, j = 2
i = 1, j = 0
跳出外层循环

goto 语句

goto 用于无条件跳转到指定标签:

package main

import "fmt"

func main() {
    i := 0

start:
    fmt.Printf("i = %d\n", i)
    i++
    if i < 5 {
        goto start
    }
}

输出:

i = 0
i = 1
i = 2
i = 3
i = 4

注意:goto 容易造成代码混乱,建议谨慎使用。

实际案例

案例 1:猜数字游戏

package main

import (
    "fmt"
    "math/rand"
    "time"
)

func main() {
    rand.Seed(time.Now().UnixNano())
    target := rand.Intn(100) + 1

    fmt.Println("猜数字游戏(1-100)")

    for {
        var guess int
        fmt.Print("请输入你的猜测: ")
        fmt.Scan(&guess)

        if guess < target {
            fmt.Println("太小了,再试试!")
        } else if guess > target {
            fmt.Println("太大了,再试试!")
        } else {
            fmt.Println("恭喜你,猜对了!")
            break
        }
    }
}

案例 2:打印菱形

package main

import "fmt"

func main() {
    n := 5

    for i := 1; i <= n; i++ {
        for j := 1; j <= n-i; j++ {
            fmt.Print(" ")
        }
        for j := 1; j <= 2*i-1; j++ {
            fmt.Print("*")
        }
        fmt.Println()
    }

    for i := n - 1; i >= 1; i-- {
        for j := 1; j <= n-i; j++ {
            fmt.Print(" ")
        }
        for j := 1; j <= 2*i-1; j++ {
            fmt.Print("*")
        }
        fmt.Println()
    }
}

输出:

    *
   ***
  *****
 *******
*********
 *******
  *****
   ***
    *

案例 3:判断素数

package main

import "fmt"

func isPrime(n int) bool {
    if n < 2 {
        return false
    }
    for i := 2; i*i <= n; i++ {
        if n%i == 0 {
            return false
        }
    }
    return true
}

func main() {
    fmt.Println("100 以内的素数:")
    for i := 2; i <= 100; i++ {
        if isPrime(i) {
            fmt.Printf("%d ", i)
        }
    }
    fmt.Println()
}

总结

本章学习了 Go 语言的流程控制:

语句说明
if条件判断
for循环(可模拟 while)
switch多条件选择
break跳出循环
continue跳过本次循环
goto无条件跳转