目录
正在加载目录…
专栏文章
专栏文章
GoLang 专栏
1. GoLang:语法、并发与工程实践 2. GoLang 类型系统:接口、泛型与数据结构 3. 并发编程 4. GoLang 错误处理:error、panic 与 defer 5. GoLang 标准库速查:高频包与实战用法 6. GoLang 工程实践:项目结构、测试与部署

GoLang:语法、并发与工程实践

发布于 2026-07-06 22:29 · 最后编辑于 2026-07-31 15:51 · 字数 2,146 👁 86 次阅读

Go(又称 Golang)是 Google 于 2009 年发布的开源编译型静态类型语言,由 Robert Griesemer、Rob Pike、Ken Thompson 设计。 目标是兼顾 C 的性能与 Python 的开发效率,内置并发原语(goroutine / channel),特别适合构建网络服务、CLI 工具和云原生应用。

相关文章GoLang 类型系统与数据结构深度 · GoLang 并发编程 · GoLang 错误处理与 panic-defer · GoLang 标准库速查 · GoLang 工程实践

⚠️ 版本说明:本文以 Go 1.22+ 为基准,所有代码示例均可直接运行。部分特性(泛型 1.18+range over integers 1.22+)在低版本不可用。

目录

章节说明
核心特性设计哲学、与其他语言的对比
安装与工具链安装、GOPATH/GOROOT、常用命令
基础语法变量、常量、基本类型、零值
函数多返回值、命名返回值、变参、defer
流程控制if、for、switch、goto
复合类型array、slice、map、struct
指针基本用法、与 C 的区别
方法与接口值/指针接收者、接口、空接口、类型断言
错误处理error 接口、自定义错误、panic/recover
并发goroutine、channel、select、sync
包与模块package、go mod、常用标准库
快速参考卡类型速查、内置函数速查

核心特性

../../assets/01 GoLang 简介/file 20260605123651505

设计哲学

特性说明
编译型直接编译为机器码,无需运行时,启动极快
静态类型编译期类型检查,减少运行时错误
垃圾回收自动内存管理,无需手动 malloc/free
内置并发goroutine + channel,并发模型简洁高效
工具链统一go fmtgo testgo build 开箱即用
依赖极简单二进制输出,无外部动态库依赖
无继承通过组合(embedding)和接口实现多态

与其他语言对比

维度GoJavaPython
编译方式编译为原生二进制编译为字节码(JVM)解释执行
并发模型goroutine(M:N 调度)线程GIL 限制
类型系统静态、强类型静态、强类型动态、强类型
启动速度极快(毫秒级)慢(JVM 预热)
内存占用
泛型1.18+ 支持支持支持

安装与工具链

安装

# macOS(推荐 Homebrew)
brew install go

# 验证
go version   # go version go1.22.x darwin/arm64

重要环境变量

go env GOROOT    # Go 安装目录(标准库所在位置)
go env GOPATH    # 工作区目录,默认 ~/go
go env GOMODCACHE  # 模块缓存目录,默认 ~/go/pkg/mod
go env GOPROXY   # 模块代理,国内推荐设置:
go env -w GOPROXY=https://goproxy.cn,direct

常用工具命令

go run main.go           # 编译并运行(开发调试用)
go build .               # 编译当前包,生成可执行文件
go build -o app .        # 指定输出文件名
go install .             # 编译并安装到 $GOPATH/bin

go test ./...            # 运行所有测试
go test -v ./...         # 详细输出
go test -run TestFoo     # 只运行匹配的测试

go fmt ./...             # 格式化代码(强制统一风格)
go vet ./...             # 静态检查常见错误
go mod tidy              # 整理依赖(添加缺失、删除多余)

go get github.com/pkg@v1.2.3   # 添加/升级依赖
go doc fmt.Println             # 查看文档

创建第一个项目

mkdir hello && cd hello
go mod init hello          # 初始化模块,生成 go.mod

创建 main.go

package main

import "fmt"

func main() {
    fmt.Println("Hello, Go!")
}
go run main.go    # 输出:Hello, Go!

基础语法

变量声明

package main

import "fmt"

func main() {
    // 方式一:var 声明(显式类型)
    var name string = "Alice"
    var age int = 30

    // 方式二:var 声明(类型推断)
    var city = "Beijing"

    // 方式三:短变量声明(函数内最常用)
    score := 98.5

    // 多变量声明
    var x, y int = 1, 2
    a, b := "hello", true

    // 批量声明
    var (
        host = "localhost"
        port = 8080
    )

    fmt.Println(name, age, city, score, x, y, a, b, host, port)
}

零值(Zero Value)

Go 中所有变量声明后都有默认零值,不存在未初始化的变量:

package main

import "fmt"

func main() {
    var i int       // 0
    var f float64   // 0.0
    var b bool      // false
    var s string    // ""(空字符串)
    var p *int      // nil
    fmt.Println(i, f, b, s, p)
}

常量

package main

import "fmt"

// 常量在编译期求值,不可修改
const Pi = 3.14159
const MaxRetry = 3

// iota:枚举常量自动递增
type Weekday int

const (
    Sunday Weekday = iota   // 0
    Monday                  // 1
    Tuesday                 // 2
    Wednesday               // 3
)

// iota 的其他用法
const (
    KB = 1 << (10 * (iota + 1))   // 1024
    MB                             // 1048576
    GB                             // 1073741824
)

func main() {
    fmt.Println(Pi, MaxRetry)
    fmt.Println(Sunday, Monday, Tuesday)
    fmt.Println(KB, MB, GB)
}

基本类型

类型说明零值
bool布尔值false
int / int8/16/32/64有符号整数0
uint / uint8/16/32/64无符号整数0
float32 / float64浮点数0
complex64 / complex128复数0
stringUTF-8 字符串(不可变字节序列)""
byteuint8 的别名0
runeint32 的别名,表示 Unicode 码点0
package main

import "fmt"

func main() {
    // 类型转换(Go 不做隐式转换,必须显式)
    var i int = 42
    f := float64(i)
    u := uint(f)
    fmt.Println(i, f, u)

    // 字符串与 []byte 互转
    s := "Hello, 世界"
    b := []byte(s)
    r := []rune(s)
    fmt.Println(len(s))  // 13(字节数)
    fmt.Println(len(b))  // 13(字节数)
    fmt.Println(len(r))  // 9(字符数)
}

函数

基本定义

package main

import "fmt"

// 基本函数
func add(a, b int) int {
    return a + b
}

// 多返回值(Go 特色)
func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, fmt.Errorf("除数不能为零")
    }
    return a / b, nil
}

// 命名返回值(适合短函数,增加可读性)
func minMax(nums []int) (min, max int) {
    min, max = nums[0], nums[0]
    for _, v := range nums[1:] {
        if v < min {
            min = v
        }
        if v > max {
            max = v
        }
    }
    return   // naked return,返回命名变量的当前值
}

// 可变参数
func sum(nums ...int) int {
    total := 0
    for _, n := range nums {
        total += n
    }
    return total
}

func main() {
    fmt.Println(add(3, 4))   // 7

    result, err := divide(10, 3)
    if err != nil {
        fmt.Println("错误:", err)
    } else {
        fmt.Printf("%.4f\n", result)   // 3.3333
    }

    lo, hi := minMax([]int{3, 1, 4, 1, 5, 9})
    fmt.Println(lo, hi)   // 1 9

    fmt.Println(sum(1, 2, 3, 4, 5))   // 15

    // 展开 slice 传入可变参数
    nums := []int{1, 2, 3}
    fmt.Println(sum(nums...))   // 6
}

defer

package main

import "fmt"

func main() {
    // defer 在函数返回前执行,多个 defer 按 LIFO 顺序执行
    defer fmt.Println("3: 最后执行")
    defer fmt.Println("2: 第二执行")
    fmt.Println("1: 先执行")
    // 输出顺序:1 → 2 → 3
}
package main

import (
    "fmt"
    "os"
)

// defer 最常见用途:确保资源释放
func readFile(path string) error {
    f, err := os.Open(path)
    if err != nil {
        return err
    }
    defer f.Close()   // 无论后续如何,函数返回前必定关闭文件

    buf := make([]byte, 64)
    n, err := f.Read(buf)
    if err != nil {
        return err
    }
    fmt.Printf("读取了 %d 字节\n", n)
    return nil
}

func main() {
    // 创建测试文件
    os.WriteFile("/tmp/go_test.txt", []byte("hello go"), 0644)
    readFile("/tmp/go_test.txt")
}

函数作为值与闭包

package main

import "fmt"

// 函数类型
type MathFunc func(int, int) int

func apply(f MathFunc, a, b int) int {
    return f(a, b)
}

// 闭包:函数捕获外部变量
func makeCounter() func() int {
    count := 0
    return func() int {
        count++
        return count
    }
}

func main() {
    add := func(a, b int) int { return a + b }
    fmt.Println(apply(add, 3, 4))   // 7

    counter := makeCounter()
    fmt.Println(counter())   // 1
    fmt.Println(counter())   // 2
    fmt.Println(counter())   // 3
}

流程控制

if

package main

import "fmt"

func classify(score int) string {
    // if 的初始化语句:变量作用域限定在 if 块内
    if grade := score / 10; grade == 10 || grade == 9 {
        return "A"
    } else if grade >= 8 {
        return "B"
    } else if grade >= 6 {
        return "C"
    } else {
        return "F"
    }
}

func main() {
    fmt.Println(classify(95))   // A
    fmt.Println(classify(72))   // C
}

for(Go 唯一的循环语句)

package main

import "fmt"

func main() {
    // 经典三段式(类 C)
    for i := 0; i < 5; i++ {
        fmt.Print(i, " ")   // 0 1 2 3 4
    }
    fmt.Println()

    // 只有条件(类 while)
    n := 1
    for n < 100 {
        n *= 2
    }
    fmt.Println(n)   // 128

    // 无限循环
    count := 0
    for {
        count++
        if count >= 3 {
            break
        }
    }
    fmt.Println(count)   // 3

    // range 遍历(1.22+ 支持 range over integer)
    for i := range 5 {
        fmt.Print(i, " ")   // 0 1 2 3 4
    }
    fmt.Println()

    // range 遍历 slice
    fruits := []string{"apple", "banana", "cherry"}
    for i, v := range fruits {
        fmt.Printf("%d: %s\n", i, v)
    }

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

    // range 遍历 string(按 rune)
    for i, r := range "Hello, 世界" {
        fmt.Printf("%d: %c\n", i, r)
    }
}

switch

package main

import (
    "fmt"
    "runtime"
)

func main() {
    // 基本 switch(无需 break,默认不穿透)
    day := 3
    switch day {
    case 1, 7:
        fmt.Println("周末")
    case 2, 3, 4, 5, 6:
        fmt.Println("工作日")
    default:
        fmt.Println("无效")
    }

    // 无条件 switch(等价于 if-else if 链)
    score := 85
    switch {
    case score >= 90:
        fmt.Println("A")
    case score >= 80:
        fmt.Println("B")   // 输出 B
    default:
        fmt.Println("C")
    }

    // fallthrough:显式穿透到下一个 case
    switch runtime.GOOS {
    case "darwin":
        fmt.Println("macOS")
        fallthrough
    case "linux":
        fmt.Println("类 Unix 系统")
    }
}

复合类型

array(固定长度)

package main

import "fmt"

func main() {
    // 数组长度是类型的一部分,[3]int 和 [4]int 是不同类型
    var a [3]int
    b := [3]int{1, 2, 3}
    c := [...]int{4, 5, 6, 7}   // 编译器推断长度

    fmt.Println(a)         // [0 0 0]
    fmt.Println(b)         // [1 2 3]
    fmt.Println(len(c))    // 4

    // 数组是值类型,赋值会复制
    d := b
    d[0] = 99
    fmt.Println(b[0], d[0])   // 1 99(互不影响)
}

slice(动态数组,最常用)

package main

import "fmt"

func main() {
    // 创建 slice
    s1 := []int{1, 2, 3}
    s2 := make([]int, 3)        // len=3, cap=3
    s3 := make([]int, 3, 10)    // len=3, cap=10

    // 切片操作(左闭右开)
    s := []int{0, 1, 2, 3, 4, 5}
    fmt.Println(s[1:4])    // [1 2 3]
    fmt.Println(s[:3])     // [0 1 2]
    fmt.Println(s[3:])     // [3 4 5]

    // append:超出 cap 时自动扩容(约 2 倍)
    s1 = append(s1, 4, 5)
    s1 = append(s1, []int{6, 7}...)
    fmt.Println(s1)        // [1 2 3 4 5 6 7]

    // copy:深拷贝
    dst := make([]int, len(s1))
    n := copy(dst, s1)
    fmt.Println(dst, n)    // [1 2 3 4 5 6 7] 7

    // slice 是引用类型,共享底层数组
    a := []int{1, 2, 3}
    b := a[:]
    b[0] = 99
    fmt.Println(a[0])   // 99(a 也被修改了)

    fmt.Println(s2, s3)
}

map

package main

import "fmt"

func main() {
    // 创建 map
    m1 := map[string]int{"a": 1, "b": 2}
    m2 := make(map[string]int)   // 空 map,推荐用 make

    // 增改
    m2["key"] = 100
    m1["c"] = 3

    // 查询(comma ok 惯用法)
    val, ok := m1["a"]
    fmt.Println(val, ok)   // 1 true

    val, ok = m1["z"]
    fmt.Println(val, ok)   // 0 false(不存在时返回零值)

    // 删除
    delete(m1, "a")

    // 遍历(顺序不固定)
    for k, v := range m1 {
        fmt.Printf("%s: %d\n", k, v)
    }

    fmt.Println(len(m1))
}

struct

package main

import "fmt"

type Person struct {
    Name string
    Age  int
    Email string
}

// 方法(见下一章节)
func (p Person) String() string {
    return fmt.Sprintf("%s(%d)", p.Name, p.Age)
}

// 嵌套与组合(Go 的"继承"方式)
type Employee struct {
    Person           // 嵌入(匿名字段),提升 Person 的字段和方法
    Company string
    Salary  float64
}

func main() {
    // 字面量初始化(推荐按字段名)
    p := Person{Name: "Alice", Age: 30, Email: "alice@example.com"}
    fmt.Println(p)          // {Alice 30 alice@example.com}
    fmt.Println(p.String()) // Alice(30)

    // 指针
    pp := &Person{Name: "Bob", Age: 25}
    pp.Age = 26             // 自动解引用,等价于 (*pp).Age = 26
    fmt.Println(pp.Age)     // 26

    // 嵌入:可直接访问 Person 的字段
    e := Employee{
        Person:  Person{Name: "Charlie", Age: 35},
        Company: "ACME",
        Salary:  50000,
    }
    fmt.Println(e.Name, e.Company)   // Charlie ACME
    fmt.Println(e.String())          // Charlie(35)(提升的方法)

    // 匿名结构体(一次性使用)
    point := struct {
        X, Y int
    }{X: 1, Y: 2}
    fmt.Println(point)   // {1 2}
}

指针

package main

import "fmt"

func increment(n *int) {
    *n++   // 解引用并修改
}

func newInt(v int) *int {
    // Go 允许返回局部变量的指针,编译器自动将其分配到堆上
    return &v
}

func main() {
    x := 42
    p := &x          // p 是指向 x 的指针,类型为 *int

    fmt.Println(x)   // 42
    fmt.Println(p)   // 0xc0000...(内存地址)
    fmt.Println(*p)  // 42(解引用)

    *p = 100
    fmt.Println(x)   // 100(x 被修改)

    increment(&x)
    fmt.Println(x)   // 101

    // new:分配零值内存,返回指针
    q := new(int)    // *int,值为 0
    *q = 99
    fmt.Println(*q)  // 99

    ptr := newInt(10)
    fmt.Println(*ptr)   // 10

    // Go 没有指针运算(不能 p++),比 C 更安全
}

方法与接口

方法

package main

import (
    "fmt"
    "math"
)

type Circle struct {
    Radius float64
}

type Rectangle struct {
    Width, Height float64
}

// 值接收者:方法内操作的是副本,不修改原值
func (c Circle) Area() float64 {
    return math.Pi * c.Radius * c.Radius
}

// 指针接收者:可修改原值,大结构体时避免复制开销(推荐统一用指针接收者)
func (c *Circle) Scale(factor float64) {
    c.Radius *= factor
}

func (r Rectangle) Area() float64 {
    return r.Width * r.Height
}

func main() {
    c := Circle{Radius: 5}
    fmt.Printf("面积: %.2f\n", c.Area())   // 78.54

    c.Scale(2)   // Go 自动取地址:(&c).Scale(2)
    fmt.Printf("缩放后半径: %.1f\n", c.Radius)   // 10.0

    r := Rectangle{Width: 3, Height: 4}
    fmt.Printf("面积: %.2f\n", r.Area())   // 12.00
}

接口

package main

import (
    "fmt"
    "math"
)

// 接口:定义行为契约,隐式实现(无需 implements 关键字)
type Shape interface {
    Area() float64
    Perimeter() float64
}

type Circle struct{ Radius float64 }
type Rectangle struct{ Width, Height float64 }

func (c Circle) Area() float64      { return math.Pi * c.Radius * c.Radius }
func (c Circle) Perimeter() float64 { return 2 * math.Pi * c.Radius }

func (r Rectangle) Area() float64      { return r.Width * r.Height }
func (r Rectangle) Perimeter() float64 { return 2 * (r.Width + r.Height) }

func printShape(s Shape) {
    fmt.Printf("面积=%.2f  周长=%.2f\n", s.Area(), s.Perimeter())
}

func main() {
    shapes := []Shape{
        Circle{Radius: 5},
        Rectangle{Width: 3, Height: 4},
    }
    for _, s := range shapes {
        printShape(s)
    }
}

类型断言与类型 switch

package main

import "fmt"

func describe(i interface{}) {
    // 类型 switch
    switch v := i.(type) {
    case int:
        fmt.Printf("int: %d\n", v)
    case string:
        fmt.Printf("string: %q\n", v)
    case bool:
        fmt.Printf("bool: %v\n", v)
    default:
        fmt.Printf("未知类型: %T\n", v)
    }
}

func main() {
    describe(42)
    describe("hello")
    describe(true)
    describe(3.14)

    // 单次类型断言
    var i interface{} = "world"
    s, ok := i.(string)
    fmt.Println(s, ok)   // world true

    n, ok := i.(int)
    fmt.Println(n, ok)   // 0 false(断言失败,返回零值)
}

错误处理

error 接口

package main

import (
    "errors"
    "fmt"
)

// error 是内置接口:type error interface { Error() string }

func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, errors.New("除数不能为零")
    }
    return a / b, nil
}

// fmt.Errorf 支持格式化,%w 包裹原始错误(用于 errors.Is / errors.As)
func readConfig(path string) error {
    if path == "" {
        return fmt.Errorf("readConfig: %w", errors.New("路径不能为空"))
    }
    return nil
}

func main() {
    if result, err := divide(10, 3); err != nil {
        fmt.Println("错误:", err)
    } else {
        fmt.Printf("%.4f\n", result)   // 3.3333
    }

    if _, err := divide(1, 0); err != nil {
        fmt.Println("错误:", err)   // 错误: 除数不能为零
    }

    err := readConfig("")
    fmt.Println(err)   // readConfig: 路径不能为空
}

自定义错误类型

package main

import (
    "errors"
    "fmt"
)

type ValidationError struct {
    Field   string
    Message string
}

func (e *ValidationError) Error() string {
    return fmt.Sprintf("[%s] %s", e.Field, e.Message)
}

func validate(email string) error {
    if email == "" {
        return &ValidationError{Field: "email", Message: "不能为空"}
    }
    return nil
}

func main() {
    err := validate("")
    if err != nil {
        fmt.Println(err)   // [email] 不能为空

        // errors.As:提取特定类型的错误
        var ve *ValidationError
        if errors.As(err, &ve) {
            fmt.Println("字段:", ve.Field)   // 字段: email
        }
    }
}

panic 与 recover

package main

import "fmt"

// recover 必须在 defer 中调用才有效
func safeDiv(a, b int) (result int, err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("捕获 panic: %v", r)
        }
    }()
    return a / b, nil   // b==0 时触发 panic: runtime error: integer divide by zero
}

func main() {
    result, err := safeDiv(10, 2)
    fmt.Println(result, err)   // 5 <nil>

    result, err = safeDiv(10, 0)
    fmt.Println(result, err)   // 0 捕获 panic: runtime error: integer divide by zero
}

原则:Go 中用 error 处理预期错误,panic 只用于不可恢复的程序错误(如数组越界、空指针)。库代码中不应将 panic 暴露给调用方。

并发

goroutine

package main

import (
    "fmt"
    "sync"
    "time"
)

func worker(id int, wg *sync.WaitGroup) {
    defer wg.Done()
    fmt.Printf("worker %d 开始\n", id)
    time.Sleep(time.Millisecond * 100)
    fmt.Printf("worker %d 结束\n", id)
}

func main() {
    var wg sync.WaitGroup

    // 启动 5 个 goroutine 并发执行
    for i := 1; i <= 5; i++ {
        wg.Add(1)
        go worker(i, &wg)
    }

    wg.Wait()   // 等待所有 goroutine 完成
    fmt.Println("所有 worker 完成")
}

channel

package main

import "fmt"

func sum(nums []int, ch chan int) {
    total := 0
    for _, n := range nums {
        total += n
    }
    ch <- total   // 发送结果到 channel
}

func main() {
    nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

    ch := make(chan int)   // 无缓冲 channel

    go sum(nums[:5], ch)
    go sum(nums[5:], ch)

    a, b := <-ch, <-ch   // 接收两个结果
    fmt.Println(a, b, a+b)   // 15 40 55(或 40 15 55,顺序不定)

    // 带缓冲 channel:发送方不阻塞,直到缓冲区满
    buffered := make(chan int, 3)
    buffered <- 1
    buffered <- 2
    buffered <- 3
    fmt.Println(<-buffered)   // 1

    // range channel:直到 channel 关闭
    jobs := make(chan int, 5)
    for i := 1; i <= 5; i++ {
        jobs <- i
    }
    close(jobs)
    for j := range jobs {
        fmt.Print(j, " ")   // 1 2 3 4 5
    }
    fmt.Println()
}

select

package main

import (
    "fmt"
    "time"
)

func main() {
    ch1 := make(chan string)
    ch2 := make(chan string)

    go func() {
        time.Sleep(50 * time.Millisecond)
        ch1 <- "one"
    }()
    go func() {
        time.Sleep(30 * time.Millisecond)
        ch2 <- "two"
    }()

    // select:等待多个 channel,哪个先就绪就处理哪个
    for i := 0; i < 2; i++ {
        select {
        case msg := <-ch1:
            fmt.Println("收到 ch1:", msg)
        case msg := <-ch2:
            fmt.Println("收到 ch2:", msg)
        }
    }

    // 带超时的 select
    ch := make(chan int)
    select {
    case v := <-ch:
        fmt.Println("收到:", v)
    case <-time.After(100 * time.Millisecond):
        fmt.Println("超时")   // 输出:超时
    }
}

sync 常用原语

package main

import (
    "fmt"
    "sync"
)

func main() {
    // Mutex:互斥锁,保护共享数据
    var mu sync.Mutex
    counter := 0
    var wg sync.WaitGroup

    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            mu.Lock()
            counter++
            mu.Unlock()
        }()
    }
    wg.Wait()
    fmt.Println("counter:", counter)   // 1000

    // Once:确保某操作只执行一次(如单例初始化)
    var once sync.Once
    for i := 0; i < 3; i++ {
        once.Do(func() {
            fmt.Println("只执行一次")
        })
    }
}

包与模块

package 规则

// 每个文件第一行声明所属包
package main   // 可执行程序的入口包,必须有 main 函数

// 包名通常与目录名一致,小写,简短
// 导出标识符:首字母大写(Public)
// 未导出标识符:首字母小写(package private)

go mod 模块管理

# 初始化模块
go mod init github.com/yourname/myproject

# 添加依赖(自动更新 go.mod 和 go.sum)
go get github.com/gin-gonic/gin@v1.9.1

# 整理依赖(删除未使用,添加缺失)
go mod tidy

# 查看依赖图
go mod graph

# 下载所有依赖到本地缓存
go mod download

# vendor 模式(将依赖复制到项目 vendor 目录)
go mod vendor
go build -mod=vendor ./...

常用标准库速览

package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "os"
    "path/filepath"
    "strings"
    "time"
)

func main() {
    // strings:字符串处理
    fmt.Println(strings.Contains("hello world", "world"))   // true
    fmt.Println(strings.Split("a,b,c", ","))                // [a b c]
    fmt.Println(strings.Join([]string{"x", "y"}, "-"))      // x-y
    fmt.Println(strings.TrimSpace("  hi  "))                // hi
    fmt.Println(strings.ToUpper("hello"))                   // HELLO
    fmt.Println(strings.ReplaceAll("aabbcc", "b", "X"))     // aaXXcc

    // fmt:格式化
    s := fmt.Sprintf("name=%s age=%d", "Alice", 30)
    fmt.Println(s)   // name=Alice age=30

    // time:时间处理
    now := time.Now()
    fmt.Println(now.Format("2006-01-02 15:04:05"))   // Go 的参考时间是固定的
    tomorrow := now.Add(24 * time.Hour)
    fmt.Println(tomorrow.Format("2006-01-02"))

    // os:操作系统接口
    fmt.Println(os.Getenv("HOME"))
    os.WriteFile("/tmp/go_demo.txt", []byte("hello"), 0644)
    data, _ := os.ReadFile("/tmp/go_demo.txt")
    fmt.Println(string(data))   // hello

    // filepath:跨平台路径操作
    p := filepath.Join("/tmp", "dir", "file.txt")
    fmt.Println(p)                      // /tmp/dir/file.txt
    fmt.Println(filepath.Base(p))       // file.txt
    fmt.Println(filepath.Dir(p))        // /tmp/dir
    fmt.Println(filepath.Ext(p))        // .txt

    // encoding/json:JSON 序列化
    type Person struct {
        Name string `json:"name"`
        Age  int    `json:"age"`
    }
    person := Person{Name: "Alice", Age: 30}
    b, _ := json.Marshal(person)
    fmt.Println(string(b))   // {"name":"Alice","age":30}

    var p2 Person
    json.Unmarshal(b, &p2)
    fmt.Println(p2.Name, p2.Age)   // Alice 30

    // net/http:HTTP 客户端
    resp, err := http.Get("https://httpbin.org/get")
    if err == nil {
        fmt.Println("状态码:", resp.StatusCode)
        resp.Body.Close()
    }
}

快速参考卡

基本类型速查

类型位宽范围 / 说明零值
booltrue / falsefalse
int平台相关(32/64)有符号整数0
int88 bit-128 ~ 1270
int1616 bit-32768 ~ 327670
int32 / rune32 bitUnicode 码点0
int6464 bit大整数0
uint8 / byte8 bit0 ~ 2550
float3232 bit单精度浮点0
float6464 bit双精度浮点(推荐)0
stringUTF-8 不可变字节序列""
error内置接口nil

内置函数速查

函数说明
len(v)返回 string/array/slice/map/channel 的长度
cap(v)返回 slice/channel 的容量
make(T, args)创建 slice、map、channel(返回引用)
new(T)分配零值内存,返回 *T
append(s, v...)向 slice 追加元素
copy(dst, src)复制 slice,返回复制的元素数
delete(m, k)删除 map 中的键
close(ch)关闭 channel
panic(v)触发 panic
recover()在 defer 中捕获 panic
print / println内置输出(调试用,推荐用 fmt)

常用符号速查

符号含义
:=短变量声明(仅函数内)
&v取变量地址,返回指针
*p解引用指针
<-ch从 channel 接收
ch <-向 channel 发送
...可变参数 / 展开 slice
_空白标识符,忽略返回值

参考资料

← 返回列表

评论 (0)

暂无评论,来留下第一条吧。
登录注册 后才能发表评论