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 详情