经过十几年漫长的“自给自足”,Go 语言终于要在 1.28 版本迎来标准库的泛型集合类型(Set、有序 Map 等)。这波操作虽然像是一位“拖延症晚期患者”的补作业,但迟到总比缺席好。本文将带你以幽默的视角,围观 Go 团队这次“知耻而后勇”的大动作。
如果你是一个 Go 语言开发者,那么对于下面这个“经典”场景一定不陌生:想要一个集合(Set)?官方答案永远只有一个——自己动手,丰衣足食。
// Go 语言官方推荐的“集合”写法,充满了程序员式的无奈与智慧
type StringSet map[string]struct{}
func (s StringSet) Add(v string) { s[v] = struct{}{} }
func (s StringSet) Has(v string) bool { _, ok := s[v]; return ok }
// 如果要并集、交集?对不起,请自己写循环,每次都得重新发明轮子
是不是很优雅?(手动狗头)。map[T]struct{} 这个惯用法,虽然能干活,但总给人一种“用着炒菜锅去盛汤”的凑合感 。
现在,救星终于要来了!根据最新的社区提案 #80590,由 Robert Griesemer、Ian Lance Taylor 等七位 Go 语言核心大佬组成的 Go Collections 工作组,计划在 Go 1.28 中正式为标准库引入原生泛型集合类型 。这消息一出,Hacker News 上立刻炸开了锅,热度高达 432 点 ,足以见证 gopher 们多年的“怨念”有多深。
新货上架:告别“手搓”时代
那么,这次 Go 团队到底要给我们上什么“硬菜”呢?简单来说,就是一套完整的泛型集合“全家桶”。
| set.Set[T] | 标准泛型集合 | 告别 map[T]struct{},直接使用 Union、Intersect 等清晰方法 |
| container/hash | 支持自定义哈希的 Set/Map | 允许使用切片、Map 等不可比较的类型作为键,解决泛型 comparable 约束的不足 |
| container/tree | 有序树形 Map | 提供了标准库长久以来缺失的有序 Map 实现,基于平衡树,遍历键值对不再需要先排序 |
| container/heap/v2 | 新一代泛型堆 | 替代当前“反人类”的 container/heap 接口,使用体验将大幅提升 |
想象一下,未来的代码可以写成这样:
// AFTER: 梦想中的 Go 1.28 写法
a := set.New("alice", "bob")
b := set.New("bob", "carol")
union := a.Union(b) // 结果: {alice, bob, carol}
inter := a.Intersect(b) // 结果: {bob}
是不是清爽多了?
为何姗姗来迟?Go 团队的“完美主义”拖延症
看到这里,你可能会问:既然泛型在 Go 1.18 (2022年) 就出来了,为啥拖到 1.28 才搞集合库?答案是:Go 团队在等另一个“拼图”——迭代器 (range-over iterators) 。
Go 语言的哲学是,标准库提供的功能,必须和内置类型一样“趁手”。如果没有迭代器,就算实现了 Set,你也没法直接用 for range 遍历,那体验感会大打折扣 。所以,直到 Go 1.23 引入了迭代器特性后,补上集合库的时机才算真正成熟 。
这四年不是空窗期,而是 Go 团队在憋一个大招,力求一步到位,给出一个体面、完整的解决方案 。
不止是加功能:Go 的“克制”与权衡
作为一个以“简洁”为信仰的语言,Go 在添加新特性时总是异常谨慎,这次也不例外。提案中明确了两点“克制” :
社区狂欢与吐槽:这很 Go
和任何重大提案一样,社区里也是“锣鼓喧天,鞭炮齐鸣”,顺便夹杂着一些熟悉的“Go 式吐槽”。
- 支持派:“虽然晚了 22 年,但迟到总比不到好。”
- 担忧派:担心 Go 会变得像 C++/Java 一样复杂,“集大成者”最终变成“四不像”。
- 命名吐槽:有人认为 Union、Intersection 这些数学术语太学术,不够“接地气”。(喂,写代码的难道不是搞数学逻辑的吗?)
而最大的赢家,可能是那些靠写 map[T]struct{} 工具库而获得几千 star 的开源项目,比如 deckarep/golang-set。随着这些功能进入标准库,它们的历史使命也即将圆满完成 。
总结:更好的 Go,它来了
无论你是兴奋还是担忧,Go 1.28 的泛型集合都代表了这门语言的一次重要演进。它补齐了长久以来的一个短板,让 Go 在工程实践中的表达力更强。
所以,放下手中正在写的 map[T]bool 吧,让我们拭目以待 Go 1.28 的到来。毕竟,能用标准库解决的,谁还自己写轮子呢?



