Skip to content
Go
Go 版本标准库变更速查

Go 版本标准库变更速查

本文记录 Go 各版本中标准库的重要新增和变更,方便快速查阅"某个功能从哪个版本开始可用"。


Go 1.26 (2026年2月)

变更 说明
递归泛型约束 语言 泛型接口可自引用:type Adder[A Adder[A]] interface { Add(A) A }
new(expr) 语法 语言 new 支持初始化表达式:p := new(int, 42)
Green Tea GC 默认启用 runtime 新垃圾回收器,小对象密集型应用 GC 开销降低 10-40%
实验性 SIMD 支持 archsimd 跨平台 SIMD 向量运算(实验性)
泛型方法(实验性) 语言 GOEXPERIMENT=genericmethods,泛型类型的方法可引入自己的类型参数。预计 Go 1.27 正式发布
堆随机化 runtime ASLR 增强,堆起始地址随机化
更快 cgo cgo cgo 调用开销降低约 50%
runtime/secret runtime/secret 安全擦除敏感数据(密码、密钥等内存清零)
// Go 1.26: 递归泛型 — 接口约束可以引用自身
type Mergeable[T Mergeable[T]] interface {
    Merge(other T) T
}

// Go 1.26: new(expr) — 带初始化表达式的 new
p := new(int, 42)        // *int, 指向 42
s := new(MyStruct, "a", 1) // 等价于 &MyStruct{Field1: "a", Field2: 1}

// Go 1.26 实验性:泛型方法 (GOEXPERIMENT=genericmethods)
func (b *Builder) Build[T any]() (T, error) { ... }
user, err := b.Build[User]()

Go 1.25 (2025年8月)

变更 说明
删除「核心类型」概念 语言 规范层面简化泛型规则:过去 ~[]byte | ~string 无法切片,现在基于类型集检查,合法编译
testing/synctest 稳定 testing/synctest 虚拟时钟 + 确定性 goroutine 编排,并发测试无需真实等待超时
容器感知 GOMAXPROCS runtime Linux 上自动检测 cgroup CPU 配额,容器中延迟降约 40%
encoding/json/v2(实验性) encoding/json/v2 新 JSON 引擎,反序列化速度提升 3-10 倍,零堆分配
Flight Recorder API runtime 轻量级运行时追踪录制到环形缓冲区
DWARF v5 默认 工具链 二进制体积减约 30%,链接速度提升 20-40%
go.mod ignore go 忽略 node_modules 等无关目录,加速 go test ./...
go vet 新分析器 go vet waitgroup(错误 Add 调用)、hostport(建议 net.JoinHostPort
// Go 1.25: 无「核心类型」后,更宽泛的约束变得合法
type Sliceable interface { ~[]byte | ~string }
func Slice[T Sliceable](s T) T {
    return s[1:3]  // Go 1.25: ✅ 合法(之前:❌ 无核心类型)
}

Go 1.24 (2025年2月)

变更 说明
泛型类型别名 语言 type Alias[P constraint] = Original[P]
os.Root os 限制文件系统操作的根目录,防止目录遍历攻击
sync.Map.Clear sync 清空 map
strings.Lines/SplitSeq strings 迭代器版字符串分割(LinesSplitSeqFieldsSeq…)
bytes.Lines/SplitSeq bytes 迭代器版字节分割
testing/synctest(实验性) testing/synctest 测试中的确定性时间控制
crypto/rand Reader 优化 crypto/rand 弃用 Read 改用 ReadFull(更安全的 API)
mime 类型模式匹配 mime * 匹配整个类型
// Go 1.24: 泛型类型别名
type Set[K comparable] = map[K]struct{}  // 别名,非新类型

// Go 1.24: os.Root — 安全的文件系统沙箱
root, _ := os.OpenRoot("/safe/dir")
defer root.Close()

// 所有操作被限制在 /safe/dir 下
file, _ := root.Open("subdir/file.txt")      // ✅ /safe/dir/subdir/file.txt
file, _ := root.Open("../../../etc/passwd")  // ❌ 拒绝访问!

Go 1.23 (2024年8月)

变更 说明
iter iter 实验性Seq/Seq2 迭代器类型标准化
unique unique 实验性:值去重/驻留(interning)
structs structs 实验性:运行时修改结构体字段
time.Timer/Ticker 改进 time Timer.ResetTicker.Reset 不再需要先 Stop
slices.Repeat slices 重复 slice 元素
cookie 包增强 net/http Cookie.Quoted 支持引号值
// Go 1.23: slices.Repeat
s := slices.Repeat([]string{"a", "b"}, 3)
// → ["a", "b", "a", "b", "a", "b"]

// Go 1.23: 更安全的 Timer.Reset
timer := time.NewTimer(1 * time.Second)
// 不再需要:
// if !timer.Stop() { <-timer.C }
timer.Reset(2 * time.Second) // 直接 Reset 即可

🚨 Go 1.23 开始 GOPATH 模式正式移除,go get 不再在 GOPATH 模式下安装二进制。


Go 1.23 (2024年8月)

变更 说明
range over func 语言 for v := range customIter — 自定义迭代器
iter iter iter.Seq[V]iter.Seq2[K, V] 泛型迭代器类型
structs structs 实验性:运行时修改结构体字段
unique unique 实验性:值去重/驻留(interning)
time.Timer/Ticker 改进 time Reset 不再需要先 Stop
slices.Repeat slices 重复 slice 元素
cookie 包增强 net/http Cookie.Quoted 支持引号值
slices.All/Backward/Collect slices 迭代器:AllSeq2ValuesSeqCollect[]E
maps.All/Keys/Values maps 迭代器:AllSeq2KeysSeq[K]ValuesSeq[V]
// Go 1.23: range over func — 自定义迭代器
func countdown(n int) iter.Seq[int] {
    return func(yield func(int) bool) {
        for i := n; i > 0; i-- {
            if !yield(i) { return }
        }
    }
}
for v := range countdown(3) {
    fmt.Println(v)  // 3, 2, 1
}

// Go 1.23: slices 迭代器
for i, v := range slices.All([]string{"a", "b"}) {
    fmt.Println(i, v)  // 0 a, 1 b
}

Go 1.22 (2024年2月)

变更 说明
net/http 增强路由 net/http HandleFunc 支持 GET/POST 方法和 {id} 路径参数
math/rand/v2 math/rand/v2 新版随机数包,修复 Intn(0) panic 等问题
for range int 语言 for i := range 10 迭代 0..9
cmp.Or cmp 返回第一个非零值
slices.Concat slices 拼接多个 slice
// Go 1.22: 增强路由
mux := http.NewServeMux()
mux.HandleFunc("GET /users/{id}", func(w http.ResponseWriter, r *http.Request) {
    id := r.PathValue("id")  // 提取路径参数
    fmt.Fprintf(w, "User: %s", id)
})

// Go 1.22: cmp.Or
host := cmp.Or(cfg.Host, "localhost")  // 等价于 if cfg.Host != "" { host = cfg.Host } else { host = "localhost" }

// Go 1.22: slices.Concat
all := slices.Concat([]int{1, 2}, []int{3, 4}, []int{5})
// → [1, 2, 3, 4, 5]

Go 1.21 (2023年8月)

变更 说明
log/slog log/slog 结构化日志,替代 log 的事实标准
maps maps 泛型 map 操作:CloneCopyDeleteFuncEqual
slices slices 泛型 slice 操作:ContainsSortBinarySearch
cmp cmp Compare 函数和 Ordered 约束
sync.OnceFunc sync 返回一个只执行一次的函数
context.WithoutCancel context 创建不随父 context 取消的子 context
errors.ErrUnsupported errors 表示"不支持的操作"的哨兵错误
// Go 1.21: slog 结构化日志
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
logger.Info("request", "method", "GET", "path", "/api", "latency", 5*time.Millisecond)

// Go 1.21: OnceFunc
var initDB = sync.OnceFunc(func() {
    db = connectDB()
})
initDB() // 第一次调用执行
initDB() // 后续调用无操作

// Go 1.21: WithoutCancel
ctx := context.WithoutCancel(parentCtx)
// ctx 不会随 parentCtx 的取消而取消,适合异步清理任务

Go 1.20 (2023年2月)

变更 说明
errors.Join errors 合并多个错误
time.DateTime/DateOnly/TimeOnly time 预定义格式常量(终于不用手写 "2006-01-02 15:04:05" 了)
bytes.Clone bytes 复制字节切片
strings.Clone strings 复制字符串(释放底层大数组)
sync.Map 新方法 sync SwapCompareAndSwapCompareAndDelete
context.WithCancelCause context 取消时记录原因
// Go 1.20: errors.Join
err := errors.Join(err1, err2, err3)
// errors.Is(err, err1) → true

// Go 1.20: 终于不需要手写格式字符串了
fmt.Println(time.Now().Format(time.DateTime)) // "2006-01-02 15:04:05"

// Go 1.20: 释放大字符串的底层内存
sub := strings.Clone(bigString[1000:1010]) // sub 不再持有 bigString 的底层数组

Go 1.19 (2022年8月)

变更 说明
sync/atomic 新类型 sync/atomic atomic.Int32atomic.Int64atomic.Bool 等(不用手动 atomic.AddInt64(&x, 1) 了)
atomic.Pointer sync/atomic 泛型原子指针
net/url.JoinPath net/url 安全拼接 URL 路径
os/exec 增强 os/exec Cmd 支持 CancelWaitDelay
fmt.Append fmt 追加格式化输出到 []byte
// Go 1.19: 原子类型
var count atomic.Int64
count.Add(1)
val := count.Load()

var ready atomic.Bool
ready.Store(true)

// Go 1.19: URL 安全拼接
u, _ := url.Parse("https://example.com/api")
full, _ := u.JoinPath("v1", "users") // https://example.com/api/v1/users

Go 1.18 (2022年3月)

变更 说明
泛型 (Generics) 语言 Go 历史上最大的语言变更
any builtin interface{} 的别名
comparable builtin 可比较类型约束
Fuzzing testing FuzzXxx 模糊测试
net/netip net/netip 新的 IP 地址类型(替代 net.IP,不可变且可比较)
debug/buildinfo debug/buildinfo 读取二进制构建信息
strings.Cut strings 在分隔符处切割字符串
// Go 1.18: 泛型
func Max[T constraints.Ordered](a, b T) T {
    if a > b { return a }
    return b
}

// Go 1.18: strings.Cut
before, after, found := strings.Cut("key=value", "=")
// before="key", after="value", found=true

// Go 1.18: netip — 更安全、可比较、占用更小
addr := netip.MustParseAddr("192.168.1.1")     // 不可变类型
prefix := netip.MustParsePrefix("10.0.0.0/8")  // CIDR
fmt.Println(prefix.Contains(addr))             // false

💡 迁移建议:新代码中 IP 地址应优先使用 netip.Addr 而非 net.IPnetip.Addr 是不可变的值类型(可直接用 == 比较),占用更小(24 字节 vs 16+ 字节切片头),且性能更好。


版本判断最佳实践

编译时版本判断

// 使用 build tags
//go:build go1.21

// 使用 Go 1.21+ 的 go.mod 版本指令
// go 1.21

运行时版本判断

// 检查是否有某个符号/包
// 通常不推荐运行时判断,应依赖编译时语义

💡 选择基准版本:如果不需要泛型,Go 1.16 是很好的基线(embed + io/fs)。如果需要泛型,Go 1.21 是推荐的基线(标准库 slices/maps 齐备)。


相关链接