Go 1.28 的七个集合提案:Union 为什么要拆成两个函数,Get 和 At 又在争什么
2026-07-28,Go 集合工作组在 issue #80590 挂出伞形提案(umbrella proposal),里程碑定在 Go 1.28。成员:Jonathan Amsterdam、Alan Donovan、Robert Griesemer、Daniel Martí、Roger Peppe、Keith Randall、Ian Lance Taylor。
七个关联提案:
| Issue | 包 | 作用 |
|---|---|---|
| #70471 | hash/maphash.Hasher | 自定义哈希与等价判断的标准接口,Go 1.27 已发布 |
| #69559 | container/hash.Map[K,V] | 接受自定义 Hasher 的哈希表 |
| #80584 | container/hash.Set[T] | 基于自定义哈希的集合 |
| #69230 | container/set.Set[T] | 可比较元素的规范集合,底层 map[T]struct{} |
| #77052 | container/mapset | 把存量 map[T]bool / map[T]struct{} 当集合用的辅助函数 |
| #60630 | container/tree.Map[K,V] | 平衡二叉树上的有序 map,支持范围查询 |
| #77397 | container/heap/v2.Heap | 泛型堆,替换旧的接口式 API |
后续还有一轮:插入有序的哈希 map(#80194)和泛型 Stack。
Hasher 已经落地。它解决两类问题:key 不可比较(slice、map),或者默认的相等语义不对——go/types 里的 types.Type 就需要 types.Identical 做深比较。文档里带了一个 Bloom filter 的示例。
函数式 Union 与 UnionWith 为什么分开
函数式形式返回新集合,不碰操作数;可变形式带 -With 后缀,比如 UnionWith。理由有两条:避免「到底改没改」的歧义,以及调用者忘了接返回值那类 bug。代价很直接——分配 vs 原地修改,用哪个由调用方自己权衡,库不替你做选择。
Get / At:省一次查找,代价是命名争议
为了省掉第二次查找,Map 的方法都返回状态:Set 返回旧值 + bool(原来是否存在),Delete 报告 key 是否存在,Get 返回 value + 存在性,At 只返回值(缺失时给零值)。
命名并未定论。有人偏好 Lookup / GetCheck;也有人认为 Get 就该是带检查的那个,而 At 不符合 Go 的命名习惯。
subset / superset / Take 没进接口
这三个留在主 set 约束之外,由要求更少的泛型辅助函数实现。树形 set 判断不相交区间的子集可以更快,但一旦把方法写进接口,所有实现都得提供。
树形 Map 只在范围查询时才值得
container/tree.Map 的核心卖点是不用重建有序 key 列表就能做范围扫描。没有范围查询需求的场景,它不比哈希表多给什么。
DeleteFunc 为什么必须在接口里
树一次遍历就能清掉所有匹配元素;反复调 Delete 则是 O(n log n)。O(n) 与 O(n log n) 的差距没法靠外部循环补回来,所以 DeleteFunc 留在 map/set 的 API 里。
F-bounded 约束为什么不外露
普通 Go 接口表达不了 Union(S) S 这种跨无关集合类型的约束,所以用了递归泛型约束(F-bounded polymorphism)。抽象的 Collection / Map / Set 约束一律不导出:公开约束会限制以后的设计空间,先积累使用经验再决定要不要定型。
兼容与实现顺序
mapset 是给那些 API 已经钉死在 map[T]bool 上的存量代码准备的,不改变类型,语义与 set.Set 的方法一致。
首版实现只对 API 行为和渐近复杂度负责,常数因子优化放到后面。
现状
issue 上的反应是 69 赞、30 爱心、20 火箭、6 踩。这只能说明关注度,不是采用率。提案还要走 review、实现、发布批准,签名和 API 在 Go 1.28 之前都可能变。Go 1.28 预计 2027 年初发布。
- 提案:https://github.com/golang/go/issues/80590
- 发布说明:https://go.dev/doc/go1.28
- 相关阅读:https://tonybai.com/2026/07/29/go-1-28-generic-collections-proposal/