首页 / Go 语言入门教程 / slices 标准库(1.21+)

Go 语言入门教程

slices 标准库(1.21+)

本教程共 80 篇 · 第 31 篇 · 更新于 2026-07-27 · 约 7 分钟阅读

GoGo 入门教程slices标准库排序CloneContains

31. slices 标准库(1.21+)

本节目标:学会用 Go 1.21 新增的 slices 标准库,一行代码搞定排序、查找、克隆、反转等常见操作。

为什么需要 slices 包

在 Go 1.21 之前,给切片排序要用 sort 包,写起来挺啰嗦的。查找元素得自己写循环,克隆切片得用 copy。Go 1.21 终于把这些常用操作收进了标准库,包名就叫 slices

Note

slices 包是 Go 1.21(2023 年 8 月)引入的。如果你用的 Go 版本低于 1.21,需要先升级。

排序:slices.Sort

Sort 对切片做升序排序,直接修改原切片:

package main

import (
    "fmt"
    "slices"
)

func main() {
    s := []int{3, 1, 4, 1, 5, 9, 2, 6}
    slices.Sort(s)
    fmt.Println(s) // [1 1 2 3 4 5 6 9]
}

如果想降序排,排完反转一下就行:

slices.Sort(s)
slices.Reverse(s)
fmt.Println(s) // [9 6 5 4 3 2 1 1]

Sort 要求元素是可排序的类型(实现了 cmp.Ordered 约束,包括数字和字符串)。如果你要排自定义结构体,用 SortFunc

package main

import (
    "cmp"
    "fmt"
    "slices"
)

type Person struct {
    Name string
    Age  int
}

func main() {
    people := []Person{
        {"Alice", 30},
        {"Bob", 25},
        {"Charlie", 35},
    }

    slices.SortFunc(people, func(a, b Person) int {
        return cmp.Compare(a.Age, b.Age)
    })

    fmt.Println(people)
    // [{Bob 25} {Alice 30} {Charlie 35}]
}

SortFunc 接收一个比较函数,返回负数表示 a 在前,正数表示 b 在前,0 表示相等。cmp.Compare 是 Go 1.21 新增的工具函数,帮你写比较逻辑。

查找:slices.Contains 和 slices.Index

Contains 判断切片里有没有某个值:

s := []int{1, 2, 3, 4, 5}
fmt.Println(slices.Contains(s, 3)) // true
fmt.Println(slices.Contains(s, 6)) // false

Index 返回第一个匹配元素的下标,找不到返回 -1:

s := []string{"apple", "banana", "cherry"}
fmt.Println(slices.Index(s, "banana")) // 1
fmt.Println(slices.Index(s, "grape"))  // -1
Tip

Go 1.21 之前,查找元素你得自己写 for 循环。现在一行函数调用搞定,代码清爽多了。

克隆:slices.Clone

Clone 创建一个底层数组独立的副本:

s := []int{1, 2, 3}
cloned := slices.Clone(s)

cloned[0] = 100
fmt.Println(s)       // [1 2 3]  原切片没变
fmt.Println(cloned)  // [100 2 3]

等价于 append([]T(nil), s...),但用 Clone 更直观。

反转:slices.Reverse

Reverse 原地反转切片:

s := []int{1, 2, 3, 4, 5}
slices.Reverse(s)
fmt.Println(s) // [5 4 3 2 1]

二分查找:slices.BinarySearch

如果切片已经排好序了,用二分查找比遍历快得多:

s := []int{1, 3, 5, 7, 9, 11}

pos, found := slices.BinarySearch(s, 7)
fmt.Println(pos, found)   // 3 true

pos, found = slices.BinarySearch(s, 8)
fmt.Println(pos, found)   // 4 false

返回两个值:找到的话是下标和 true,没找到的话是「应该插入的位置」和 false。

其他常用函数

slices 包还有不少好用的函数,列几个常见的:

函数作用
slices.Min(s)返回最小值
slices.Max(s)返回最大值
slices.Equal(a, b)比较两个切片是否相等
slices.Delete(s, i, j)删除下标 i 到 j 的元素
slices.Insert(s, i, v...)在下标 i 处插入元素
slices.Compact(s)去掉连续重复的元素
slices.Grow(s, n)预留 n 个元素的容量
slices.IsSorted(s)判断是否已排序

来个 InsertDelete 的例子:

package main

import (
    "fmt"
    "slices"
)

func main() {
    s := []int{1, 2, 4, 5}

    // 在下标2处插入3
    s = slices.Insert(s, 2, 3)
    fmt.Println(s) // [1 2 3 4 5]

    // 删除下标1到3(不含3)的元素
    s = slices.Delete(s, 1, 3)
    fmt.Println(s) // [1 4 5]
}

以前自己写 append 拼接来删除元素,现在直接调 Delete,省心多了。

Warning

slices.Sortslices.Reverse直接修改原切片,不会返回新的。如果你不想动原切片,先 Clone 再操作。

小结

slices 标准库把以前手写的切片操作全收编了:

  • 排序用 Sort / SortFunc
  • 查找用 Contains / Index / BinarySearch
  • 复制用 Clone
  • 增删用 Insert / Delete
  • 反转用 Reverse

从 Go 1.21 开始,写切片操作代码再也不用造轮子了。下一部分我们进入 map 的世界。