Go 内置函数clear

Go 内置函数 clear 封面

clear 是什么

clear 是 Go 1.21 引入的内置泛型函数,清空切片或映射:

func clear[T ~[]Type | ~map[Type]Type1](t T)

类型参数只接受切片和映射两类。清空后容器仍可继续使用,这是它和重新分配的本质区别。

对不同类型的行为

类型行为结果示例
切片把所有元素置为零值,保留 len 和 cap[0 0 0 0](len=4, cap=4)
映射删除所有键值对map[](len=0)
泛型容器类型参数须为切片/映射类型,行为与上一致—
clear 对切片与映射的行为对比
图 1:clear 对切片与映射的行为——切片元素归零且保留 len/cap,映射全部删除且 len=0
// 切片:元素归零,长度容量不变
s := []int{1, 2, 3, 4}
clear(s)
fmt.Println(s)          // [0 0 0 0],len=4, cap=4

// 映射:清空
m := map[string]int{"A": 1, "B": 2}
clear(m)
fmt.Println(m)          // map[],len=0

// 自定义泛型切片
type MySlice[T any] []T
ms := MySlice[string]{"Go", "Gopher"}
clear(ms)               // ["", ""]

关键注意点

  • clear 不释放内存:切片元素归零但底层数组保留,容量不变。需要真正释放时手动置 nil(s = nil)或新建切片;
  • NaN 键也能删:映射里以 NaN 为键的条目普通遍历删不掉(NaN ≠ NaN),clear 能正确清除——这是它比”遍历删除”更可靠的地方;
  • 清空 ≠ 置 nil:要区分”复用容器”(clear,保留容量避免重新分配)和”释放内存”(置 nil);
  • 泛型约束:自定义类型必须本质是切片或映射(如 type MyMap[K comparable, V any] map[K]V)。
clear 清空与置 nil 的内存差异
图 2:清空与置 nil 的内存去向——clear 保留底层数组供复用,置 nil 把内存交给 GC

适用场景

  • 快速重置容器:替代手动循环置零/逐键删除,代码简洁且语义清晰;
  • 内存复用:连接池、对象池里清空切片再复用,减少分配;
  • 泛型代码统一:一个 clear 同时处理切片和映射,无需分别实现。
滚动至顶部