ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Go 1.28 新提案:Set、有序 Map 等泛型集合强势来袭

Go 1.28 新提案:Set、有序 Map 等泛型集合强势来袭 经过十几年漫长的“自给自足”Go 语言终于要在 1.28 版本迎来标准库的泛型集合类型Set、有序 Map 等。这波操作虽然像是一位“拖延症晚期患者”的补作业但迟到总比缺席好。本文将带你以幽默的视角围观 Go 团队这次“知耻而后勇”的大动作。如果你是一个 Go 语言开发者那么对于下面这个“经典”场景一定不陌生想要一个集合Set官方答案永远只有一个——自己动手丰衣足食。// Go 语言官方推荐的“集合”写法充满了程序员式的无奈与智慧typeStringSetmap[string]struct{}func(s StringSet)Add(vstring){s[v]struct{}{}}func(s StringSet)Has(vstring)bool{_,ok:s[v];returnok}// 如果要并集、交集对不起请自己写循环每次都得重新发明轮子是不是很优雅手动狗头。map[T]struct{}这个惯用法虽然能干活但总给人一种“用着炒菜锅去盛汤”的凑合感 。现在救星终于要来了根据最新的社区提案 #80590由 Robert Griesemer、Ian Lance Taylor 等七位 Go 语言核心大佬组成的Go Collections 工作组计划在Go 1.28中正式为标准库引入原生泛型集合类型 。这消息一出Hacker News 上立刻炸开了锅热度高达 432 点 足以见证 gopher 们多年的“怨念”有多深。新货上架告别“手搓”时代那么这次 Go 团队到底要给我们上什么“硬菜”呢简单来说就是一套完整的泛型集合“全家桶”。包 (Package)核心功能解决痛点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 在添加新特性时总是异常谨慎这次也不例外。提案中明确了两点“克制” 不追求“极致”性能初版的目标是保证 API 正确和渐近复杂度比如 O(log n)但不会为了微小的常数级性能提升而过度设计。先求“对”再求“快”。暂不公开抽象接口为了解决集合类型中经典的“二元方法问题”Binary Method Problem比如两个不同实现的Set如何比较工作组设计了一套基于 F-bounded 多态的抽象接口。但这些接口目前仅作为内部文档不对外导出避免过早地锁定公共 API 契约体现了 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 的到来。毕竟能用标准库解决的谁还自己写轮子呢
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进