Skip to content

Go 语言标准库

Go 语言拥有丰富而强大的标准库,涵盖了从基础数据处理到网络编程、文件操作、加密等各个方面。掌握标准库的使用是成为 Go 开发高手的关键。

📋 标准库概览

核心包分类

  • 基础包:fmt、strings、strconv、time、math 等
  • 容器包:container/list、container/heap、container/ring
  • I/O 包:io、bufio、ioutil、os、path、filepath
  • 网络包:net、net/http、net/url、net/smtp
  • 加密包:crypto、crypto/md5、crypto/sha256、crypto/tls
  • 编码包:encoding/json、encoding/xml、encoding/base64
  • 并发包:sync、context、runtime
  • 测试包:testing、testing/quick

🔤 字符串处理(strings)

基本字符串操作

go
package main

import (
    "fmt"
    "strings"
)

func stringBasics() {
    text := "Go Programming Language"
    
    fmt.Println("=== 字符串基础操作 ===")
    
    // 查找操作
    fmt.Printf("包含 'Go': %t\n", strings.Contains(text, "Go"))
    fmt.Printf("包含前缀 'Go': %t\n", strings.HasPrefix(text, "Go"))
    fmt.Printf("包含后缀 'Language': %t\n", strings.HasSuffix(text, "Language"))
    
    // 索引操作
    fmt.Printf("'Programming' 的位置: %d\n", strings.Index(text, "Programming"))
    fmt.Printf("最后一个 'a' 的位置: %d\n", strings.LastIndex(text, "a"))
    
    // 计数
    fmt.Printf("字母 'g' 出现次数: %d\n", strings.Count(text, "g"))
    
    // 大小写转换
    fmt.Printf("大写: %s\n", strings.ToUpper(text))
    fmt.Printf("小写: %s\n", strings.ToLower(text))
    fmt.Printf("标题: %s\n", strings.Title(text))
}

func stringManipulation() {
    fmt.Println("\n=== 字符串操作 ===")
    
    // 分割和连接
    text := "apple,banana,orange,grape"
    fruits := strings.Split(text, ",")
    fmt.Printf("分割结果: %v\n", fruits)
    
    joined := strings.Join(fruits, " | ")
    fmt.Printf("连接结果: %s\n", joined)
    
    // 替换
    original := "Hello World, Hello Go"
    replaced := strings.Replace(original, "Hello", "Hi", 1)  // 替换一次
    replacedAll := strings.ReplaceAll(original, "Hello", "Hi") // 全部替换
    
    fmt.Printf("原文: %s\n", original)
    fmt.Printf("替换一次: %s\n", replaced)
    fmt.Printf("全部替换: %s\n", replacedAll)
    
    // 修剪空白
    messy := "  \t\n  Go Programming  \t\n  "
    fmt.Printf("原文: '%s'\n", messy)
    fmt.Printf("修剪空白: '%s'\n", strings.TrimSpace(messy))
    fmt.Printf("修剪字符: '%s'\n", strings.Trim("...Go...", "."))
}

func main() {
    stringBasics()
    stringManipulation()
}

字符串构建器

go
package main

import (
    "fmt"
    "strings"
)

func stringBuilderDemo() {
    fmt.Println("=== 字符串构建器 ===")
    
    var builder strings.Builder
    
    // 写入字符串
    builder.WriteString("Hello")
    builder.WriteString(" ")
    builder.WriteString("World")
    
    // 写入字符
    builder.WriteByte('!')
    
    // 写入格式化字符串
    fmt.Fprintf(&builder, " 当前长度: %d", builder.Len())
    
    result := builder.String()
    fmt.Printf("构建结果: %s\n", result)
    fmt.Printf("字符串长度: %d\n", len(result))
    fmt.Printf("构建器容量: %d\n", builder.Cap())
    
    // 重置构建器
    builder.Reset()
    fmt.Printf("重置后长度: %d\n", builder.Len())
}

func main() {
    stringBuilderDemo()
}

🕐 时间处理(time)

时间基础操作

go
package main

import (
    "fmt"
    "time"
)

func timeBasics() {
    fmt.Println("=== 时间基础操作 ===")
    
    // 获取当前时间
    now := time.Now()
    fmt.Printf("当前时间: %v\n", now)
    
    // 时间格式化(Go 的特殊格式化方式)
    fmt.Printf("格式化时间: %s\n", now.Format("2006-01-02 15:04:05"))
    fmt.Printf("自定义格式: %s\n", now.Format("2006年01月02日 15:04:05"))
    fmt.Printf("RFC3339: %s\n", now.Format(time.RFC3339))
    
    // 创建特定时间
    birthday := time.Date(1990, 5, 15, 14, 30, 0, 0, time.UTC)
    fmt.Printf("生日: %s\n", birthday.Format("2006-01-02 15:04:05"))
    
    // 解析时间字符串
    timeStr := "2023-12-25 15:30:00"
    parsed, err := time.Parse("2006-01-02 15:04:05", timeStr)
    if err != nil {
        fmt.Printf("解析错误: %v\n", err)
    } else {
        fmt.Printf("解析时间: %s\n", parsed.Format("2006-01-02 15:04:05"))
    }
}

func timeCalculations() {
    fmt.Println("\n=== 时间计算 ===")
    
    now := time.Now()
    
    // 时间加减
    oneHourLater := now.Add(time.Hour)
    twoDaysAgo := now.Add(-48 * time.Hour)
    
    fmt.Printf("当前时间: %s\n", now.Format("2006-01-02 15:04:05"))
    fmt.Printf("一小时后: %s\n", oneHourLater.Format("2006-01-02 15:04:05"))
    fmt.Printf("两天前: %s\n", twoDaysAgo.Format("2006-01-02 15:04:05"))
    
    // 时间比较
    future := now.Add(time.Hour)
    fmt.Printf("未来时间在当前时间之后: %t\n", future.After(now))
    fmt.Printf("当前时间在未来时间之前: %t\n", now.Before(future))
    
    // 时间差
    duration := future.Sub(now)
    fmt.Printf("时间差: %v\n", duration)
    fmt.Printf("小时数: %.2f\n", duration.Hours())
    fmt.Printf("分钟数: %.2f\n", duration.Minutes())
}

func timerAndTicker() {
    fmt.Println("\n=== 定时器和计时器 ===")
    
    // 定时器 - 只执行一次
    timer := time.NewTimer(100 * time.Millisecond)
    fmt.Println("定时器创建,等待...")
    
    <-timer.C
    fmt.Println("定时器触发!")
    
    // 计时器 - 周期性执行
    ticker := time.NewTicker(50 * time.Millisecond)
    defer ticker.Stop()
    
    count := 0
    for {
        select {
        case <-ticker.C:
            count++
            fmt.Printf("计时器第 %d 次触发\n", count)
            if count >= 3 {
                return
            }
        }
    }
}

func main() {
    timeBasics()
    timeCalculations()
    timerAndTicker()
}

🔢 数学计算(math)

基础数学函数

go
package main

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

func mathBasics() {
    fmt.Println("=== 基础数学函数 ===")
    
    // 基本运算
    fmt.Printf("绝对值 |-5.5|: %.2f\n", math.Abs(-5.5))
    fmt.Printf("向上取整 3.2: %.0f\n", math.Ceil(3.2))
    fmt.Printf("向下取整 3.8: %.0f\n", math.Floor(3.8))
    fmt.Printf("四舍五入 3.6: %.0f\n", math.Round(3.6))
    
    // 幂运算
    fmt.Printf("2^8: %.0f\n", math.Pow(2, 8))
    fmt.Printf("√16: %.2f\n", math.Sqrt(16))
    fmt.Printf("∛27: %.2f\n", math.Cbrt(27))
    
    // 三角函数
    angle := math.Pi / 4 // 45度
    fmt.Printf("sin(π/4): %.4f\n", math.Sin(angle))
    fmt.Printf("cos(π/4): %.4f\n", math.Cos(angle))
    fmt.Printf("tan(π/4): %.4f\n", math.Tan(angle))
    
    // 对数函数
    fmt.Printf("ln(e): %.4f\n", math.Log(math.E))
    fmt.Printf("log10(100): %.2f\n", math.Log10(100))
    fmt.Printf("log2(8): %.2f\n", math.Log2(8))
}

func mathConstants() {
    fmt.Println("\n=== 数学常量 ===")
    
    fmt.Printf("π: %.6f\n", math.Pi)
    fmt.Printf("e: %.6f\n", math.E)
    fmt.Printf("φ (黄金比例): %.6f\n", math.Phi)
    fmt.Printf("√2: %.6f\n", math.Sqrt2)
    fmt.Printf("ln(2): %.6f\n", math.Ln2)
    fmt.Printf("ln(10): %.6f\n", math.Ln10)
}

func randomNumbers() {
    fmt.Println("\n=== 随机数生成 ===")
    
    // 设置随机种子
    rand.Seed(time.Now().UnixNano())
    
    // 生成随机数
    fmt.Printf("随机整数: %d\n", rand.Int())
    fmt.Printf("0-99随机数: %d\n", rand.Intn(100))
    fmt.Printf("随机浮点数: %.4f\n", rand.Float64())
    fmt.Printf("1-6随机数: %d\n", rand.Intn(6)+1)
    
    // 生成随机序列
    fmt.Print("随机序列: ")
    for i := 0; i < 5; i++ {
        fmt.Printf("%d ", rand.Intn(10))
    }
    fmt.Println()
}

func main() {
    mathBasics()
    mathConstants()
    randomNumbers()
}

📊 JSON 处理(encoding/json)

JSON 编码解码

go
package main

import (
    "encoding/json"
    "fmt"
)

type Person struct {
    Name     string  `json:"name"`
    Age      int     `json:"age"`
    Email    string  `json:"email,omitempty"`
    Salary   float64 `json:"salary,omitempty"`
    IsActive bool    `json:"is_active"`
}

type Company struct {
    Name      string   `json:"name"`
    Founded   int      `json:"founded"`
    Employees []Person `json:"employees"`
}

func jsonBasics() {
    fmt.Println("=== JSON 基础操作 ===")
    
    // 创建结构体实例
    person := Person{
        Name:     "张三",
        Age:      30,
        Email:    "zhangsan@example.com",
        Salary:   50000.0,
        IsActive: true,
    }
    
    // 编码为 JSON
    jsonData, err := json.Marshal(person)
    if err != nil {
        fmt.Printf("编码错误: %v\n", err)
        return
    }
    
    fmt.Printf("JSON 数据: %s\n", jsonData)
    
    // 美化输出
    prettyData, err := json.MarshalIndent(person, "", "  ")
    if err != nil {
        fmt.Printf("美化编码错误: %v\n", err)
        return
    }
    
    fmt.Printf("美化 JSON:\n%s\n", prettyData)
    
    // 解码 JSON
    var decodedPerson Person
    err = json.Unmarshal(jsonData, &decodedPerson)
    if err != nil {
        fmt.Printf("解码错误: %v\n", err)
        return
    }
    
    fmt.Printf("解码结果: %+v\n", decodedPerson)
}

func jsonComplex() {
    fmt.Println("\n=== 复杂 JSON 处理 ===")
    
    company := Company{
        Name:    "技术公司",
        Founded: 2020,
        Employees: []Person{
            {Name: "张三", Age: 30, Email: "zhang@company.com", IsActive: true},
            {Name: "李四", Age: 25, Email: "li@company.com", IsActive: true},
            {Name: "王五", Age: 35, IsActive: false}, // 没有邮箱
        },
    }
    
    // 编码公司数据
    companyJSON, err := json.MarshalIndent(company, "", "  ")
    if err != nil {
        fmt.Printf("编码错误: %v\n", err)
        return
    }
    
    fmt.Printf("公司 JSON:\n%s\n", companyJSON)
    
    // 解码公司数据
    var decodedCompany Company
    err = json.Unmarshal(companyJSON, &decodedCompany)
    if err != nil {
        fmt.Printf("解码错误: %v\n", err)
        return
    }
    
    fmt.Printf("解码公司: %s, 成立于: %d\n", 
              decodedCompany.Name, decodedCompany.Founded)
    
    fmt.Println("员工列表:")
    for i, emp := range decodedCompany.Employees {
        status := "活跃"
        if !emp.IsActive {
            status = "非活跃"
        }
        fmt.Printf("  %d. %s, %d岁, %s\n", 
                  i+1, emp.Name, emp.Age, status)
    }
}

func jsonDynamic() {
    fmt.Println("\n=== 动态 JSON 处理 ===")
    
    // 处理未知结构的 JSON
    jsonStr := `{
        "name": "动态数据",
        "count": 42,
        "items": ["item1", "item2", "item3"],
        "meta": {
            "version": "1.0",
            "author": "Go"
        }
    }`
    
    var data interface{}
    err := json.Unmarshal([]byte(jsonStr), &data)
    if err != nil {
        fmt.Printf("解码错误: %v\n", err)
        return
    }
    
    // 类型断言访问数据
    if obj, ok := data.(map[string]interface{}); ok {
        if name, ok := obj["name"].(string); ok {
            fmt.Printf("名称: %s\n", name)
        }
        
        if count, ok := obj["count"].(float64); ok {
            fmt.Printf("计数: %.0f\n", count)
        }
        
        if items, ok := obj["items"].([]interface{}); ok {
            fmt.Print("项目: ")
            for _, item := range items {
                if str, ok := item.(string); ok {
                    fmt.Printf("%s ", str)
                }
            }
            fmt.Println()
        }
        
        if meta, ok := obj["meta"].(map[string]interface{}); ok {
            if version, ok := meta["version"].(string); ok {
                fmt.Printf("版本: %s\n", version)
            }
        }
    }
}

func main() {
    jsonBasics()
    jsonComplex()
    jsonDynamic()
}

🌐 HTTP 客户端(net/http)

HTTP 请求示例

go
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
    "net/url"
    "time"
)

type APIResponse struct {
    Status  string      `json:"status"`
    Message string      `json:"message"`
    Data    interface{} `json:"data"`
}

func simpleHTTPClient() {
    fmt.Println("=== 简单 HTTP 客户端 ===")
    
    // GET 请求
    resp, err := http.Get("https://httpbin.org/get")
    if err != nil {
        fmt.Printf("GET 请求错误: %v\n", err)
        return
    }
    defer resp.Body.Close()
    
    fmt.Printf("状态码: %d\n", resp.StatusCode)
    fmt.Printf("状态: %s\n", resp.Status)
    
    // 读取响应体
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Printf("读取响应错误: %v\n", err)
        return
    }
    
    var result map[string]interface{}
    if err := json.Unmarshal(body, &result); err == nil {
        if headers, ok := result["headers"].(map[string]interface{}); ok {
            if userAgent, ok := headers["User-Agent"].(string); ok {
                fmt.Printf("User-Agent: %s\n", userAgent)
            }
        }
    }
}

func customHTTPClient() {
    fmt.Println("\n=== 自定义 HTTP 客户端 ===")
    
    // 创建自定义客户端
    client := &http.Client{
        Timeout: 10 * time.Second,
    }
    
    // POST 请求
    postData := map[string]interface{}{
        "name":  "测试数据",
        "value": 123,
    }
    
    jsonData, _ := json.Marshal(postData)
    
    req, err := http.NewRequest("POST", "https://httpbin.org/post", 
                               bytes.NewBuffer(jsonData))
    if err != nil {
        fmt.Printf("创建请求错误: %v\n", err)
        return
    }
    
    // 设置请求头
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("User-Agent", "Go-HTTP-Client/1.0")
    
    resp, err := client.Do(req)
    if err != nil {
        fmt.Printf("执行请求错误: %v\n", err)
        return
    }
    defer resp.Body.Close()
    
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Printf("读取响应错误: %v\n", err)
        return
    }
    
    var result map[string]interface{}
    if err := json.Unmarshal(body, &result); err == nil {
        if data, ok := result["data"].(string); ok {
            fmt.Printf("发送的数据: %s\n", data)
        }
    }
}

func urlOperations() {
    fmt.Println("\n=== URL 操作 ===")
    
    // 解析 URL
    rawURL := "https://example.com/path?name=张三&age=30#section1"
    parsedURL, err := url.Parse(rawURL)
    if err != nil {
        fmt.Printf("URL 解析错误: %v\n", err)
        return
    }
    
    fmt.Printf("协议: %s\n", parsedURL.Scheme)
    fmt.Printf("主机: %s\n", parsedURL.Host)
    fmt.Printf("路径: %s\n", parsedURL.Path)
    fmt.Printf("查询参数: %s\n", parsedURL.RawQuery)
    fmt.Printf("锚点: %s\n", parsedURL.Fragment)
    
    // 查询参数操作
    params := parsedURL.Query()
    fmt.Printf("姓名: %s\n", params.Get("name"))
    fmt.Printf("年龄: %s\n", params.Get("age"))
    
    // 构建 URL
    newURL := &url.URL{
        Scheme: "https",
        Host:   "api.example.com",
        Path:   "/v1/users",
    }
    
    newParams := url.Values{}
    newParams.Set("page", "1")
    newParams.Set("limit", "10")
    newURL.RawQuery = newParams.Encode()
    
    fmt.Printf("构建的 URL: %s\n", newURL.String())
}

func main() {
    simpleHTTPClient()
    customHTTPClient()
    urlOperations()
}

📁 文件路径处理(path/filepath)

路径操作示例

go
package main

import (
    "fmt"
    "path/filepath"
    "strings"
)

func pathOperations() {
    fmt.Println("=== 路径操作 ===")
    
    // 路径连接
    path1 := filepath.Join("home", "user", "documents", "file.txt")
    path2 := filepath.Join("C:", "Users", "Go", "src", "main.go")
    
    fmt.Printf("连接路径1: %s\n", path1)
    fmt.Printf("连接路径2: %s\n", path2)
    
    // 路径分析
    testPath := filepath.Join("projects", "go-tutorial", "main.go")
    
    fmt.Printf("目录: %s\n", filepath.Dir(testPath))
    fmt.Printf("文件名: %s\n", filepath.Base(testPath))
    fmt.Printf("扩展名: %s\n", filepath.Ext(testPath))
    
    // 清理路径
    messyPath := "projects//go-tutorial/../go-tutorial/./main.go"
    cleanPath := filepath.Clean(messyPath)
    fmt.Printf("原路径: %s\n", messyPath)
    fmt.Printf("清理后: %s\n", cleanPath)
    
    // 绝对路径和相对路径
    if absPath, err := filepath.Abs("main.go"); err == nil {
        fmt.Printf("绝对路径: %s\n", absPath)
    }
    
    // 检查路径类型
    fmt.Printf("是否为绝对路径: %t\n", filepath.IsAbs("/home/user"))
    fmt.Printf("是否为绝对路径: %t\n", filepath.IsAbs("./main.go"))
}

func pathMatching() {
    fmt.Println("\n=== 路径匹配 ===")
    
    // 模式匹配
    patterns := []string{
        "*.go",
        "test_*.txt",
        "data/[0-9]*.csv",
    }
    
    testPaths := []string{
        "main.go",
        "test.go",
        "test_data.txt",
        "test_config.txt",
        "data/001.csv",
        "data/abc.csv",
        "readme.md",
    }
    
    for _, pattern := range patterns {
        fmt.Printf("模式: %s\n", pattern)
        for _, path := range testPaths {
            if matched, _ := filepath.Match(pattern, path); matched {
                fmt.Printf("  匹配: %s\n", path)
            }
        }
        fmt.Println()
    }
}

func pathWalk() {
    fmt.Println("=== 路径遍历 ===")
    
    // 模拟文件系统遍历
    mockFileSystem := []string{
        "project/main.go",
        "project/utils/helper.go",
        "project/models/user.go",
        "project/tests/main_test.go",
        "project/docs/readme.md",
    }
    
    fmt.Println("模拟文件结构:")
    for _, path := range mockFileSystem {
        ext := filepath.Ext(path)
        dir := filepath.Dir(path)
        name := filepath.Base(path)
        
        depth := strings.Count(path, string(filepath.Separator))
        indent := strings.Repeat("  ", depth)
        
        var fileType string
        switch ext {
        case ".go":
            fileType = "Go源文件"
        case ".md":
            fileType = "Markdown文档"
        default:
            fileType = "未知类型"
        }
        
        fmt.Printf("%s%s (%s, 目录: %s)\n", indent, name, fileType, dir)
    }
}

func main() {
    pathOperations()
    pathMatching()
    pathWalk()
}

🎓 小结

本章我们深入学习了 Go 语言的标准库:

  • 字符串处理:strings 包的各种字符串操作和构建器
  • 时间处理:time 包的时间创建、格式化、计算和定时器
  • 数学计算:math 包的基础函数、常量和随机数生成
  • JSON 处理:encoding/json 包的编码解码和动态处理
  • HTTP 客户端:net/http 和 net/url 包的网络请求操作
  • 路径处理:path/filepath 包的路径操作和匹配

Go 语言的标准库功能强大且设计优雅,掌握这些核心包的使用是开发高质量 Go 应用的基础。


接下来,我们将学习 Go 语言Web和GUI框架,了解如何构建实际的应用程序。

标准库使用建议

  • 优先使用标准库而不是第三方库
  • 熟悉常用包的 API 设计模式
  • 注意错误处理的标准库惯例
  • 善用 Go 官方文档查阅 API 详情

本站内容仅供学习和研究使用。