Go 语言 clear 函数怎么用,一次看懂 map、slice 与泛型场景

雨后青山
雨后青山
发布时间:2026-08-25 | 44人浏览过
原创

前言

项目里第一次看到 clear,很多人都会先怀疑它是不是业务代码里自定义的工具函数。实际上,它是 Go 1.21 才加入的内置能力,但真正容易混淆的不是“它能不能用”,而是它对 map 和 slice 的处理结果并不一样。本文就从官方定义、示例输出和泛型约束三部分入手,帮你快速判断它到底适合用在什么地方。

项目里突然看到 clear 时,很多人的第一反应都会是“这是不是某个本地工具函数”。但在 Go 里,它其实是 Go 1.21 新增的内置函数之一,和 max、min 一起加入标准语言能力。要真正用对它,关键不是记住“它能清理数据”,而是分清它对 map 和 slice 的处理结果完全不同,下面就结合定义和示例把这件事讲明白。

clear 是什么,在哪个版本可用

clear 是 Go 语言的内置函数,用来处理集合类型中的内容。它是在 Go1.21 中引入的,因此如果项目编译环境还停留在更早版本,就无法直接使用。

在 clear 出现之前,清理 map 往往需要手动遍历,再配合 delete 逐个删除;而对 slice,开发者通常只能自己写循环,把元素一个个重置。clear 的意义,就是把这类常见操作变成语言内置能力。

// The clear built-in function clears maps and slices.
// For maps, clear deletes all entries, resulting in an empty map.
// For slices, clear sets all elements up to the length of the slice
// to the zero value of the respective element type. If the argument
// type is a type parameter, the type parameter's type set must
// contain only map or slice types, and clear performs the operation
// implied by the type argument. If t is nil, clear is a no-op.
func clear[T ~[]Type | ~map[Type]Type1](t T)

从这段定义可以直接提炼出几个结论:

  • 对于 map,clear 会删除全部键值对,结果是一个空 map
  • 对于 slice,clear 只会把当前长度范围内的元素设为对应类型的零值
  • 如果参数是泛型类型参数,它的类型集只能包含 map 或 slice
  • 如果传入的是 nil,那么 clear 不会执行任何操作

clear 用在 map 上会发生什么

先看最容易理解的一种情况:clear(map) 会把映射中的所有元素全部移除,长度也会随之变成 0。

func main() {
    salary := map[string]int{"alice": 1000, "bob": 2000}
    fmt.Printf("salary: %v, len: %dn", salary,     len(salary))
    // output: salary: map[alice:1000 bob:2000], len: 2

    clear(salary)
    fmt.Printf("salary: %v, len: %dn", salary,     len(salary))
    // output: salary: map[], len: 0
}

这里最重要的观察点不是“元素没了”这么简单,而是 len(salary) 也同步变成了 0。也就是说,clear 对 map 的语义就是彻底清空条目,而不是保留原值做标记。

如果你的目标是快速把一个 map 置空,同时还保留这个变量本身继续复用,那么 clear 比手写遍历删除更直接,也更符合代码意图。

clear 用在 slice 上,为什么长度不会变

slice 是理解 clear 时最容易误判的地方。它不会像 map 那样“清空容器”,而只是把切片中现有元素重置为零值,切片的长度和容量都保持不变。

用便签卡片对比 clear 处理 map 和 slice 时的不同结果
clear 对 map 和 slice 的行同样是 clear,map 会被清空,slice 只是把元素重置为零值,长度与容量不变。
func main() {
    salary := []int{1000, 2000}
    fmt.Printf("salary: %v, len: %d, cap: %dn", salary, len(salary), cap(salary))
    // output: salary: [1000 2000], len: 2, cap: 2

    clear(salary)
    fmt.Printf("salary: %v, len: %d, cap: %dn", salary, len(salary), cap(salary))
    // output: salary: [0 0], len: 2, cap: 2
}

从输出可以看到,执行后切片从 [1000 2000] 变成了 [0 0],但 len 依旧是 2,cap 也还是 2。这意味着:

  • clear 不会缩短切片长度
  • clear 不会改变切片容量
  • 它只会覆盖当前可见元素,使其回到对应类型的零值

因此,如果你真正想要的是“逻辑上的空切片”,那通常还需要结合切片截断等方式来处理;而如果你的目的是把已有元素内容重置掉,同时保留底层空间,clear 就很合适。

泛型类型也能用,但类型范围有限制

clear 还支持泛型场景,不过前提很明确:类型参数的类型集必须是 map 或 slice 相关类型,不能超出这个范围。

用纸面结构图说明 clear 在泛型约束中的可用范围
clear 在泛型中的适用边界泛型场景下也能调用 clear,但类型参数的类型集只能落在 map 或 slice 范围内。

下面这个示例分别定义了一个泛型切片类型和一个泛型映射类型,随后直接调用 clear:

type SalarySlice[T int] []T
type SalaryMap[K string, V int] map[K]V

func main() {
    salarySlice := SalarySlice[int]{1000, 2000}
    clear(salarySlice)
    fmt.Printf("salarySlice: %v, len: %d, cap: %dn",     salarySlice, len(salarySlice), cap(salarySlice))
    // output: salarySlice: [0 0], len: 2, cap: 2

    salaryMap := SalaryMap[string, int]{"alice": 1000, "bob": 2000}
    clear(salaryMap)
    fmt.Printf("salaryMap: %v, len: %dn", salaryMap, len(salaryMap))
    // output: salaryMap: map[], len: 0
}

这个结果和前面普通 slice、map 的表现完全一致:

  • 泛型 slice 被重置为零值元素,但长度和容量不变
  • 泛型 map 会被清空,长度变成 0

换句话说,clear 在泛型场景下并没有引入新的行为,它只是把原本对具体类型成立的规则,延续到了符合约束的类型参数上。

什么时候适合用 clear

从能力上看,clear 并不是一个很“显眼”的新特性,但它足够实用。尤其是当代码里本来就存在“把 map 清空”或“把 slice 元素批量归零”这类需求时,直接使用内置函数会比手写循环更清晰。

不过实际使用时要先判断目标到底是哪一种:

  • 如果是 map,clear 的效果就是删除全部元素
  • 如果是 slice,clear 只是把元素设为零值,并不改变切片结构

这也是判断是否该用它的关键依据。只要把这两个语义区别记住,clear 基本就不会用错。

除了 clear 之外,Go 1.21 同期还加入了 max 和 min。这类看似小幅度的语言增强,往往不会立刻改变项目结构,但会持续降低样板代码的数量,让表达更直接。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表