Go 新提案:go doc -test,为AI时代而设计,而不是只人
深夜三点,我盯着屏幕上的 crypto/rsa 包,试图理解某个边缘场景的边界条件。文档看完了,示例跑通了,但心里总缺了一块:官方测试用例是怎么处理这个 corner case 的?
于是习惯性敲下 go doc crypto/rsa,结果——空空如也。测试代码像被施了隐身咒,明明就在 *_test.go 里躺着,却对 go doc 视而不见。
那一刻,我仿佛听见苏格拉底在耳边低语:未经审视的代码,不值得调试。
最近 Go 官方仓库里冒出一个有趣的 新提案:有人提议给 go doc 加个 -test 标志,让它能显示测试文件里的内容。
听起来很简单对吧?但如果你知道这个想法在 2015 年就被 Russ Cox 一句"测试文件不属于导出 API"给否了,事情就变得微妙起来。
# 理想中的未来(提案愿景)
$ go doc -test crypto/mlkem TestRoundTrip
package mlkem_test
func TestRoundTrip(t *testing.T) {
// 测试逻辑一目了然
}
提案作者 thatnealpatel 很聪明,他没硬刚"测试是否属于 API"这个哲学问题,而是换了个角度:时代变了,朋友。
如今的 go doc 消费者,早已不只有人类开发者。大型语言模型(LLM)正在成为新的"读者",它们需要高效、确定、低 token 消耗的方式来获取代码上下文。与其让 AI 去 grep 全网搜测试文件,不如给 go doc 开个后门,让它能"自曝家丑"。
技术细节:不是魔法,是组合艺术
这个提案最让我欣赏的地方,是它没有重新发明轮子,而是玩了一手漂亮的"标志组合拳":
| 组合用法 | 效果 | 适用场景 |
|---|---|---|
go doc -test pkg |
显示测试包中的函数/类型 | 快速浏览测试入口 |
go doc -test -src pkg.Func |
显示测试函数的完整源码 | 学习官方测试写法 |
go doc -test -u pkg |
显示未导出的测试辅助函数 | 调试复杂测试逻辑 |
go doc -test -all pkg |
显示所有测试相关符号 | 全面审计测试覆盖 |
这种设计哲学很"Go":小步快跑,组合优于继承,保持向后兼容。不加 -test 时,行为完全不变,老用户无感;需要时,一键解锁新维度。
但问题来了:测试代码的文档注释规范怎么办?
目前 go doc 只定义了导出接口的注释规范。测试函数虽然也有 // TestXxx does Y 的惯例,但远不如主代码严谨。如果 go doc -test 上线,会不会导致社区对测试注释的风格产生分裂?
这让我想起自己写测试时的"摆烂时刻":
// 有时候真的会这样写(别学我)
func TestWeirdEdgeCase(t *testing.T) {
// TODO: 写注释,明天一定
if got != want {
t.Errorf("it broke, idk why")
}
}
如果这种代码被 go doc -test 公开处刑,是促进规范,还是制造焦虑?
争议的本质:工具的"人设"不能崩
提案评论区里,有人提出了一个灵魂拷问:
如果
-test的功能不是为了"展示导出 API",那它是否应该独立成一个新工具,而不是塞进cmd/go?
这其实触及了工具设计的核心矛盾:功能边界在哪里?
go doc的初心:展示包的公共契约,帮助使用者理解"怎么用"-test的诉求:展示实现细节,帮助贡献者理解"怎么测"
两者目标用户不同,信息粒度不同,甚至"好文档"的标准都不同。强行合并,会不会让 go doc 变成四不像?
但反过来想,go doc 这些年早就"人设崩塌"了:-src 看源码,-cmd 看命令,-u 看未导出符号… 它早已不是那个单纯的"API 手册",而更像一个"代码探索器"。
正如老子所言:“穷则变,变则通,通则久。”
工具设计亦是如此。当用户需求变了、使用场景变了、甚至"读者"都从人类扩展到了模型时,固守最初的设计理念,反而可能违背"实用至上"的 Go 精神。
LLM 时代:当代码开始"自言自语"
提案里有个细节让我细思极恐:有人提到,现在的 LLM 在找不到 go doc 支持的内容时,会退而求其次用 grep 或 awk。
这意味着什么?
意味着我们正在进入一个"代码自解释"的时代。以前是人类读文档写代码,现在是模型读代码生成文档,再反过来指导人类。测试代码作为"最真实的用例",其价值被重新发现。
我最近用 Copilot 写测试时就深有体会:当它能直接"看到"同包下的测试模式时,生成的用例质量明显提升。但如果它只能靠猜测或全网搜索,结果就… 嗯,你懂的。
# 模型内心 OS:
"这个函数看起来应该测空指针,但官方怎么测的?
算了,按我的理解写吧...(生成一段能跑但风格迥异的测试)"
从这个角度看,-test 标志不只是一个功能开关,更是 Go 生态对 AI 协作的一次"接口适配"。就像当年为了 HTTP/2 调整 TLS 配置一样,工具链需要为新的"消费者"做优化。
如果这个提案通过,我会建议加个小彩蛋:
$ go doc -test -philosophy crypto/rsa
输出:
// 测试代码的哲学:
// 1. 测试是代码的"压力测试",不是"装饰艺术"
// 2. 好的测试注释应该解释"为什么测",而非"测了什么"
// 3. 如果测试复杂到需要长篇注释,考虑重构被测代码
//
// 本条注释由 -philosophy 标志生成,实际使用时请保持清醒
开个玩笑。但说真的,我觉得测试代码的文档化,核心不在于"能不能看到",而在于"怎么看才有价值"。
我的经验是:阅读测试代码时,最需要的不是函数签名,而是测试意图和边界条件。如果 -test 能优先展示测试的 // Input/Expect/Reason 结构化注释,而不是简单罗列函数列表,那才是真正的需求命中。
结语
测试代码是开发者的"后台排练",有混乱、有试错、有临时方案。全部暴露,可能促进学习,也可能制造焦虑。
go doc -test 提案的真正价值,或许不在于功能本身,而在于它逼我们思考:
在开源协作与知识传承的时代,我们该如何定义"公共知识"的边界?
是坚持"最小暴露"的保守主义,还是拥抱"最大透明"的实用主义?没有标准答案。但正如 Go 语言本身的设计哲学:简单、实用、渐进。
也许最终方案会是:-test 标志上线,但默认关闭;配合新的测试注释规范,引导社区形成共识;再给 LLM 提供专门的 API 端点,避免人类用户被信息淹没。
毕竟,好的工具不是满足所有需求,而是在复杂中找到优雅的平衡点。
“智慧的衡量标准,是改变的能力。” — 阿尔伯特·爱因斯坦
- 点赞
- 收藏
- 关注作者
评论(0)