
一个从 2017 年延续至今的提案915 条评论三代 Go 开发者参与只为决定几个字符的写法。2026 年初Go 社区距离一个期待已久也争议已久的语言特性——短函数字面量Short Function Literals——比以往任何时候都更近。这不仅仅是一个关于语法的争论它触及了 Go 语言哲学的核心在“显式”与“简洁”之间边界究竟在哪里问题所在func的“显式之累”Go 的函数字面量在回调频繁的场景下显得过于“郑重其事”了。// 场景对一个用户切片按年龄排序typeUserstruct{NamestringAgeint}users:[]User{{Alice,30},{Bob,25}}// 当前的 Go 代码必须完整写出参数和返回类型sort.Slice(users,func(i,jint)bool{returnusers[i].Ageusers[j].Age})在 Go 1.18 引入泛型以及 1.23 引入迭代器iterators之后这种“啰嗦”被放大了。我们频繁地编写高阶函数却要一遍遍地重复那些编译器明明可以从上下文推断出的类型信息。// 使用迭代器的场景冗长感更明显// 假设我们有一个 slices 包的 Collect 函数将迭代器转为切片iter:func(yieldfunc(int)bool){fori:0;i10;i{if!yield(i){return}}}numbers:slices.Collect(iter)// 开发者期望的写法只需关注逻辑而非类型// numbers : slices.Collect(fn(yield) { yield(i) })八年争论三段论战这场争论的漫长历史本身就是 Go 社区决策过程的一个缩影。第一阶段 (2017-2020)怀疑与原则提案 #21498 最初被提出时社区反应冷淡。Dave Cheney 的观点“请不要这样清晰优于聪明”代表了当时的主流意见。Go 的设计信条是“显式优于隐式”。如果编译器能推断类型它就应该让开发者写出来吗核心成员 Robert Griesemer 虽表同情但对早期语法提案并不信服。第二阶段 (2020-2023)语法大爆炸Go 1.18 引入泛型成为了转折点。像slices.SortFunc这样的函数让短函数的需求从“审美偏好”变成了“日常痛点”。随之而来的是数十种语法变体的大辩论箭头、反斜杠\、fn关键字、点符号.……讨论陷入了循环。第三阶段 (2024-至今)趋于共识一个小型工作组在 2024 年达成了初步共识。Griesemer 总结了核心需求主要好处是省略参数的类型注解。目前使用fn关键字的变体是领先者。// 当前最有希望的候选语法之一// 使用 fn 关键字类型被推断sort.Slice(users,fn(i,j)bool{returnusers[i].Ageusers[j].Age})// 如果函数体只有一个表达式甚至可以更短// sort.Slice(users, fn(i, j) users[i].Age users[j].Age)为什么这么难Go 的“简单”不是免费的Go 的“简单”是一种精心设计的结果。每增加一个特性都有成本新开发者的认知负担、语言规范中的边缘情况、工具链的复杂性以及与现有惯用法的不一致风险。短函数提案暴露了一个真正的矛盾简洁的极限在哪里我的看法是Go 团队之前的犹豫是完全正确的。func(i, j int) bool { ... }虽然冗长但它绝对清晰。对于任何阅读代码的人来说它的行为是零歧义的。引入短语法本质上是用“可推断性”换取“简洁性”这要求整个社区的学习和适应。我的看法这是一次必要的演进尽管我欣赏 Go 对显式的坚持但我认为短函数字面量是 Go 演进中必要且正确的一步前提是设计足够保守。理由一泛型改变了游戏规则。在泛型之前回调函数大多是func(interface{}) interface{}类型信息本就不明确。但有了泛型sort.Slice这样的函数拥有明确的类型签名。编译器完全有能力推断i和j是int。此时强制开发者重复书写就成了一种“惩罚”而非“保护”。理由二它降低了函数式编程的门槛。Go 正在逐步吸收函数式编程的优良特性如迭代器、slices包。如果使用这些特性的代价是不断编写冗长的匿名函数那么推广必然会受阻。短语法能让代码更专注于业务逻辑本身而非类型仪式。理由三选择最“无聊”的语法。我希望 Go 团队选择最保守、最不“聪明”的语法变体。在目前的候选中fn(i, j) int { return ... }这样的形式最符合 Go 的直觉——它只是把func换成了fn并允许省略参数类型。这是一种“增量”改进而非“颠覆”。即使你从未使用过这个新特性阅读包含它的代码时也几乎没有任何障碍。// 最终我希望看到的 Go 代码风格是渐进式的// 当你需要显式类型时依然可以完整写出complexFunc:func(xint,ystring)bool{...}// 当类型明确时选择简洁simpleSort:fn(i,j){returnij}// 类型推断 bool 返回结语八年只为几个字符如果 Go 1.27 真的引入了短函数字面量这将是自泛型以来最重要的语法变化。它标志 Go 在“显式”与“简洁”的天平上微妙地向后者的方向移动了一格。八年的争论并非毫无意义。它确保了最终进入语言的特性是经过千锤百炼、被大多数社区成员所接受的。在快速变化的软件世界里Go 的这种“慢”恰恰是其长期稳定性和生命力的保证。