Go语言快速入门Go语言快速入门
首页
基础篇
进阶篇
高阶篇
实战篇
Go官方网站
编程指南
首页
基础篇
进阶篇
高阶篇
实战篇
Go官方网站
编程指南
  • 基础篇

    • 🚀 基础篇
    • 第1章 - 环境安装
    • 第2章 - Hello World
    • 第3章 - 变量与常量
    • 第4章 - 数据类型
    • 控制流程
    • 函数
    • 数组与切片
    • Map
    • 结构体
    • 指针

控制流程

控制流程决定代码的执行顺序。Go的控制语句很简洁,没有括号!我刚开始写Go的时候,总是不自觉地加上括号,后来才逐渐适应这种简洁的风格。

if 条件语句

基本用法

age := 18

if age >= 18 {
    fmt.Println("成年人")
} else if age >= 12 {
    fmt.Println("青少年")
} else {
    fmt.Println("儿童")
}

和Java/JS的区别

// Java/JS - 条件需要括号
if (age >= 18) { ... }

// Go - 不需要括号!
if age >= 18 { ... }

if 的特殊写法(带初始化)

Go的 if 可以在条件前加一个初始化语句,变量只在if块内有效:

// 普通写法
err := doSomething()
if err != nil {
    fmt.Println(err)
}
// err 在这里还能访问

// Go特有写法(推荐!)
if err := doSomething(); err != nil {
    fmt.Println(err)
}
// err 在这里不能访问了(更安全)

这种写法在错误处理中非常常见:

if data, err := fetchData(); err != nil {
    log.Fatal(err)
} else {
    process(data)
}

for 循环

Go只有 for,没有 while 和 do-while!但 for 可以变身:

标准for循环

// 类似 Java: for (int i = 0; i < 10; i++)
for i := 0; i < 10; i++ {
    fmt.Println(i)
}

while 风格

// 类似 while(n < 10)
n := 0
for n < 10 {
    fmt.Println(n)
    n++
}

无限循环

// 类似 while(true)
for {
    fmt.Println("永远循环")
    // 需要 break 或 return 跳出
}

for-range 遍历

超级好用的遍历语法!

// 遍历切片/数组
nums := []int{1, 2, 3, 4, 5}
for index, value := range nums {
    fmt.Printf("索引: %d, 值: %d\n", index, value)
}

// 只要值,忽略索引
for _, value := range nums {
    fmt.Println(value)
}

// 只要索引
for index := range nums {
    fmt.Println(index)
}

// 遍历字符串
for i, char := range "Hello世界" {
    fmt.Printf("%d: %c\n", i, char)
}

// 遍历Map
m := map[string]int{"a": 1, "b": 2}
for key, value := range m {
    fmt.Printf("%s: %d\n", key, value)
}

break 和 continue

for i := 0; i < 10; i++ {
    if i == 3 {
        continue  // 跳过本次,继续下一次
    }
    if i == 7 {
        break     // 跳出整个循环
    }
    fmt.Println(i)  // 输出: 0, 1, 2, 4, 5, 6
}

带标签的break(跳出多层循环)

outer:
    for i := 0; i < 3; i++ {
        for j := 0; j < 3; j++ {
            if i == 1 && j == 1 {
                break outer  // 直接跳出外层循环
            }
            fmt.Printf("(%d, %d) ", i, j)
        }
    }
// 输出: (0, 0) (0, 1) (0, 2) (1, 0)

switch 语句

Go的switch超级好用,不需要break!

基本用法

day := "Monday"

switch day {
case "Monday":
    fmt.Println("周一,新的开始")
case "Friday":
    fmt.Println("周五,快乐的一天")
case "Saturday", "Sunday":  // 多个值
    fmt.Println("周末,休息日")
default:
    fmt.Println("普通的一天")
}

和Java的区别

// Java需要break
switch (day) {
    case "Monday":
        System.out.println("周一");
        break;  // 必须加,否则会穿透
    // ...
}

// Go自动break,不需要写!
switch day {
case "Monday":
    fmt.Println("周一")
    // 自动结束,不会穿透
}

想要穿透?用 fallthrough

n := 1
switch n {
case 1:
    fmt.Println("一")
    fallthrough  // 继续执行下一个case
case 2:
    fmt.Println("二")
case 3:
    fmt.Println("三")
}
// 输出: 一 二

switch 无条件表达式(更灵活)

score := 85

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

switch 带初始化

switch os := runtime.GOOS; os {
case "darwin":
    fmt.Println("macOS")
case "linux":
    fmt.Println("Linux")
case "windows":
    fmt.Println("Windows")
default:
    fmt.Printf("其他系统: %s\n", os)
}

类型switch(类型断言)

func checkType(x interface{}) {
    switch v := x.(type) {
    case int:
        fmt.Printf("整数: %d\n", v)
    case string:
        fmt.Printf("字符串: %s\n", v)
    case bool:
        fmt.Printf("布尔: %t\n", v)
    default:
        fmt.Printf("未知类型: %T\n", v)
    }
}

checkType(42)        // 整数: 42
checkType("hello")   // 字符串: hello
checkType(true)      // 布尔: true

defer 延迟执行

defer 语句会在函数返回前执行,常用于资源清理:

func readFile() {
    file, _ := os.Open("test.txt")
    defer file.Close()  // 确保文件会被关闭
    
    // 处理文件...
    // 无论如何,函数结束时都会执行 file.Close()
}

多个defer按**后进先出(LIFO)**顺序执行:

func main() {
    defer fmt.Println("1")
    defer fmt.Println("2")
    defer fmt.Println("3")
    fmt.Println("开始")
}
// 输出:
// 开始
// 3
// 2
// 1

常见用途

  1. 关闭文件/网络连接
  2. 解锁互斥锁
  3. 记录函数执行时间
  4. 恢复panic
// 记录执行时间
func slowOperation() {
    start := time.Now()
    defer func() {
        fmt.Printf("执行耗时: %v\n", time.Since(start))
    }()
    
    time.Sleep(2 * time.Second)
}

实战案例:猜数字游戏

package main

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

func main() {
    // 初始化随机数种子
    rand.Seed(time.Now().UnixNano())
    target := rand.Intn(100) + 1  // 1-100的随机数
    attempts := 0
    
    fmt.Println("🎮 猜数字游戏")
    fmt.Println("我想了一个1-100之间的数字,你来猜!")
    
    for {
        var guess int
        fmt.Print("请输入你的猜测: ")
        fmt.Scan(&guess)
        attempts++
        
        switch {
        case guess < target:
            fmt.Println("📈 太小了,再大一点!")
        case guess > target:
            fmt.Println("📉 太大了,再小一点!")
        default:
            fmt.Printf("🎉 恭喜你,猜对了!答案就是 %d\n", target)
            fmt.Printf("你一共猜了 %d 次\n", attempts)
            
            // 评价
            switch {
            case attempts <= 5:
                fmt.Println("评价: ⭐⭐⭐ 太厉害了!")
            case attempts <= 10:
                fmt.Println("评价: ⭐⭐ 不错哦!")
            default:
                fmt.Println("评价: ⭐ 继续加油!")
            }
            return
        }
    }
}

实战案例:九九乘法表

package main

import "fmt"

func main() {
    fmt.Println("九九乘法表")
    fmt.Println("================")
    
    for i := 1; i <= 9; i++ {
        for j := 1; j <= i; j++ {
            fmt.Printf("%d×%d=%-2d ", j, i, i*j)
        }
        fmt.Println()
    }
}

输出:

九九乘法表
================
1×1=1  
1×2=2  2×2=4  
1×3=3  2×3=6  3×3=9  
1×4=4  2×4=8  3×4=12 4×4=16 
...

实战案例:FizzBuzz

经典面试题,展示控制流程的灵活运用:

package main

import "fmt"

func main() {
    for i := 1; i <= 100; i++ {
        switch {
        case i%15 == 0:
            fmt.Println("FizzBuzz")
        case i%3 == 0:
            fmt.Println("Fizz")
        case i%5 == 0:
            fmt.Println("Buzz")
        default:
            fmt.Println(i)
        }
    }
}

练习

  1. 写一个程序,打印1-100中所有的偶数
  2. 写一个程序,根据输入的月份判断季节
  3. 使用for-range遍历字符串"Go语言真简单",打印每个字符
参考答案
package main

import "fmt"

func main() {
    // 1. 打印偶数
    fmt.Println("=== 1-100的偶数 ===")
    for i := 2; i <= 100; i += 2 {
        fmt.Printf("%d ", i)
    }
    fmt.Println()
    
    // 2. 判断季节
    month := 5
    switch month {
    case 3, 4, 5:
        fmt.Println("春天")
    case 6, 7, 8:
        fmt.Println("夏天")
    case 9, 10, 11:
        fmt.Println("秋天")
    case 12, 1, 2:
        fmt.Println("冬天")
    default:
        fmt.Println("无效月份")
    }
    
    // 3. 遍历字符串
    str := "Go语言真简单"
    fmt.Println("\n=== 遍历字符串 ===")
    for i, c := range str {
        fmt.Printf("位置%d: %c\n", i, c)
    }
}

控制流程掌握了,下一节学习函数!

最近更新: 2025/12/27 13:26
Contributors: 王长安
Prev
第4章 - 数据类型
Next
函数