go 1.23+ 标准库 maps/slices 支持泛型,需显式传入类型参数如 maps.clone[int, string](m),slices.delete 按索引区间删除,deletefunc 按条件删除,二者均不缩容,高频调用注意分配开销。

Go 1.21+ 原生支持泛型,不需要额外工具包
直接用标准库 maps 和 slices 包即可,它们从 Go 1.21 开始内置于 golang.org/x/exp,并在 Go 1.23 正式移入标准库 maps / slices(路径为 maps 和 slices,无需导入第三方)。如果你用的是 Go 1.23+,别再找 “泛型工具包” —— 它们就是标准库的一部分。
导入和使用 maps 时必须传入具体类型参数
maps 中的函数(如 maps.Clone、maps.Keys、maps.Values)全是泛型函数,编译器无法自动推导 map 类型的键/值类型,必须显式实例化。
常见错误:直接写 maps.Clone(m) 报错 cannot infer T and V。
- ✅ 正确写法:
maps.Clone[int, string](m)(假设m是map[int]string) - ⚠️ 注意:类型参数顺序固定为
[K, V],和 map 声明顺序一致,不能写成[V, K] - ? 如果 map 类型已定义为别名(如
type IDMap map[int]string),仍需展开写maps.Clone[int, string](m),Go 不支持从别名反推泛型参数
slices 的 Delete 和 DeleteFunc 行为容易误解
slices.Delete 是「删除指定索引区间」,不是按值删除;slices.DeleteFunc 才是按条件删元素。两者都原地修改底层数组并返回新切片头,但不会自动收缩容量。
- ❌
slices.Delete(s, 2, 4)删除索引 2 到 3(左闭右开),不是删除值等于 2 和 4 的元素 - ✅ 按值删:用
slices.DeleteFunc(s, func(x int) bool { return x == target }) - ⚠️ 容量陷阱:删完后
cap(s)不变,若后续大量追加可能意外复用旧内存 —— 真正需要收缩时得手动s = append([]int(nil), s...)
性能敏感场景下,避免在热循环里频繁调用 maps.Keys 或 slices.Clone
这些函数内部会分配新底层数组:maps.Keys 分配切片存所有 key,slices.Clone 分配等长新底层数组。高频调用会抬高 GC 压力。
- ✅ 预分配优化:如果知道 map 大小,可先
keys := make([]K, 0, len(m)),再用循环手动 append - ✅ 克隆替代:若只是临时读,考虑传指针或用只读封装,而非无脑
slices.Clone - ?
maps.Equal和slices.Equal是零分配的,适合做快速相等判断
maps 和 slices 设计克制,没提供「按 value 查 key」或「深克隆嵌套结构」这类功能 —— 它们只解决最通用、最安全的泛型集合操作。需要更复杂逻辑时,自己写几行 for 循环,往往比引入抽象层更清晰、更可控。











