编程 Go 1.28 的七个集合提案:Union 为什么要拆成两个函数,Get 和 At 又在争什么

2026-10-19 21:02:30

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包作用
#70471hash/maphash.Hasher自定义哈希与等价判断的标准接口,Go 1.27 已发布
#69559container/hash.Map[K,V]接受自定义 Hasher 的哈希表
#80584container/hash.Set[T]基于自定义哈希的集合
#69230container/set.Set[T]可比较元素的规范集合,底层 map[T]struct{}
#77052container/mapset把存量 map[T]bool / map[T]struct{} 当集合用的辅助函数
#60630container/tree.Map[K,V]平衡二叉树上的有序 map,支持范围查询
#77397container/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/
复制全文 生成海报 Go 泛型 标准库 集合

推荐文章

程序员茄子在线接单