欢迎光临
我们一直在努力

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

经过十几年漫长的“自给自足”,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 团队到底要给我们上什么“硬菜”呢?简单来说,就是一套完整的泛型集合“全家桶”。

包 (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 的到来。毕竟,能用标准库解决的,谁还自己写轮子呢?

    赞(0)
    未经允许不得转载:171主机测评 » Go 1.28 新提案:Set、有序 Map 等泛型集合强势来袭
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址