Go 的“最小惊讶原则”破功了吗?—— 一个vet 新提案引发的思考

本文永久链接 – https://tonybai.com/2025/12/09/vet-add-check-for-using-verb-q

大家好,我是Tony Bai。

Go 语言的设计哲学,一向以“简单、明确、无魔法”著称,其目标是让代码的行为尽可能符合开发者的直觉,即遵循所谓的“最小惊讶原则” (Principle of Least Astonishment)。然而,最近一个被 Go 团队接受的 go vet 新提案(NO.72850),却像一面镜子,映照出了 Go 在这条道路上的一些“盲区”。

这个提案本身很简单,但它所揭示的问题却非常深刻:当一个开发者写下 fmt.Printf(“%q”, 123) 时,他期望得到的是字符串 “123″,但实际得到的却是 ‘{\n’。这种期望与现实的巨大鸿沟,让我们不得不反思:Go 的设计,真的总是那么“不言自明”吗?

问题的核心:%q 与 string(i) 的“历史包袱”

该提案的核心,是要求 go vet 工具对 fmt.Printf 中 %q 动词的误用发出警告。%q 的文档清晰地说明,它的作用是“将一个字符字符串,格式化为一个带单引号或双引号、经过 Go 语法安全转义的字面量”。

然而,许多开发者会想当然地认为,%q 能够像 %v 或 %d 一样,处理普通的整数。这种误解导致了令人惊讶的结果:

package main

import "fmt"

func main() {
    num := 123

    // 开发者期望: "123"
    // 实际输出: '{'
    // 为什么?因为 123 是字符 '{' 的 ASCII/Unicode 码点。
    fmt.Printf("fmt.Printf(\"%%q\", 123) -> %q\n", num)
}

输出:

fmt.Printf("%q", 123) -> '{'

这个行为,与另一个 Go 新手常见的陷阱如出一辙——string(i) 整数到字符串的转换

func main() {
    num := 123

    // 开发者期望: "123"
    // 实际输出: "{"
    // 为什么?因为 string(i) 的作用是将一个 Unicode 码点转换为其对应的 UTF-8 字符串。
    fmt.Printf("string(123) -> %s\n", string(num))
}

输出:

./prog.go:11:36: conversion from int to string yields a string of one rune, not a string of digits

Go vet failed.

string(123) -> {

这两个例子共同揭示了一个问题:Go 在处理“数字”与“字符”的转换时,其行为源自 C 语言的悠久传统,但对于没有这种历史背景的现代开发者而言,这无疑是“反直觉”的。正确的做法,本应是使用 strconv.Itoa(123)。

go vet:是“创可贴”还是“守护神”?

Go 团队接受了这个提案,意味着未来的 go vet 将会像它已经对 string(i) 做的那样,对 fmt.Printf(“%q”, non_char_int) 这样的代码发出警告。

这引出了一个更深层次的讨论:我们是在用 vet 工具,为语言设计上的“瑕疵”打补丁吗?

  • 一方观点:如果一个 API 如此容易被误用,以至于需要一个外部工具来纠正它,那么这个 API 本身的设计可能就存在问题。像 printf 这种继承自 C 语言的、依赖于“格式化字符串”与可变参数类型匹配的范式,本身就是类型不安全的,难以做到“无需文档即可正确使用”。

  • 另一方观点(务实派):Go 的设计,是在表达力、性能和历史兼容性之间做出的权衡。string(i) 的行为对于处理 rune 和 byte 极其高效和方便,为了这个核心用例,牺牲一些对普通 int 的“直觉性”是值得的。printf 家族虽然有其历史包袱,但其功能强大且广为人知。

在这种权衡之下,go vet 扮演的角色,就不仅仅是一个“创可贴”,而更像是一个“守护神”。它成为了 Go 语言设计哲学的一部分,代表了一种务实的工程决策

语言本身保持小巧和高性能,而将那些复杂的、易出错的模式检查,交给一个同样作为一等公民的、可不断演进的静态分析工具链。

一个惊人的发现:%q 误用有多普遍?

为了评估这个提案的影响,Go 团队成员 Alan Donovan 对约 10,000 个开源 Go 模块进行了扫描,结果令人震惊:

  • 共发现了 42,976 处 fmt.Printf(“%q”, …) 的潜在误用!

他随机抽查了其中的几十个案例,发现几乎全是“真阳性”——开发者显然是想用 %q 来打印一个带引号的数字或普通变量,却意外地打印出了一个不相关的 Unicode 字符。

这个数据雄辩地证明,%q 的“反直觉”行为,并非个别新手的困惑,而是一个在 Go 社区中普遍存在的认知盲区。这也使得为 go vet 增加这个检查的必要性,变得无可辩驳。

小结:在“简单”与“清晰”之间求索

%q 的故事,是 Go 语言设计哲学复杂性的一次精彩展现。它告诉我们,“简单”并非一个单薄的概念。

  • string(i) 的设计,对于语言实现和 rune 处理来说,是简单的
  • fmt.Printf 的格式化动词,对于熟悉 C 传统的人来说,是简单的

但当这些“局部简单”的特性,组合在一起并呈现给一位来自不同背景的开发者时,其行为就可能不再清晰 (Clear),甚至变得“令人惊讶”。

Go 语言通过不断地为其守护神——go vet 工具——添加新的“神力”,来弥合“简单”与“清晰”之间的鸿沟。这正是Go团队承认历史,正视现实,并用工程化的手段,引导开发者走向更健壮、更正确的代码的一种务实策略。

下一次,当 go vet 在你的代码下划出波浪线时,或许你看到的,将不再是一个冰冷的警告,而是一份来自 Go 设计者们的、穿越时空的“温馨提示”。

资料链接:https://github.com/golang/go/issues/72850


你的Go技能,是否也卡在了“熟练”到“精通”的瓶颈期?

  • 想写出更地道、更健壮的Go代码,却总在细节上踩坑?
  • 渴望提升软件设计能力,驾驭复杂Go项目却缺乏章法?
  • 想打造生产级的Go服务,却在工程化实践中屡屡受挫?

继《Go语言第一课》后,我的《Go语言进阶课》终于在极客时间与大家见面了!

我的全新极客时间专栏 《Tony Bai·Go语言进阶课》就是为这样的你量身打造!30+讲硬核内容,带你夯实语法认知,提升设计思维,锻造工程实践能力,更有实战项目串讲。

目标只有一个:助你完成从“Go熟练工”到“Go专家”的蜕变! 现在就加入,让你的Go技能再上一个新台阶!


想系统学习Go,构建扎实的知识体系?

我的新书《Go语言第一课》是你的首选。源自2.4万人好评的极客时间专栏,内容全面升级,同步至Go 1.24。首发期有专属五折优惠,不到40元即可入手,扫码即可拥有这本300页的Go语言入门宝典,即刻开启你的Go语言高效学习之旅!


商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求,请扫描下方公众号二维码,与我私信联系。

给了机关枪,你却非要耍大刀:2025 年末,程序员 All in AI 的生存启示录

本文永久链接 – https://tonybai.com/2025/12/09/programmer-all-in-ai-survival-revelation-in-2025

大家好,我是Tony Bai。

最近逛 Twitter 和技术论坛,我发现了一个非常有意思,甚至有些魔幻的现象。

尽管我们已经站在了 2025 年末,距离 ChatGPT 震撼发布已经过去了整整三年,AI 能力早已从“玩具”进化成了“重型武器”。但在评论区里,依然充斥着大量这样的声音:

  • “真程序员谁用 AI 啊,那都是给脚本小子用的。”
  • “用 AI 生成代码没有灵魂,我还是习惯自己掌控每一个字符。”
  • … …

看着这些言论,再联想到身边团队和朋友圈中的一些类似的现象,我忍不住在我的知识星球中发了一句感慨:

“给了你机关枪,你却非得用大刀。这不仅是不合时宜,简直是暴殄天物”

这三年,AI 不再是那个只会写打油诗的聊天机器人,它是基建,是水电,是程序员的第二大脑。

在这个时间节点,命题早已改变:不再是“要不要用 AI”,而是“你为什么还在用大刀砍柴?”

但在真正 All in AI 之前,我们必须先看清现实中普遍存在的“四大怪象”,并一一打破它们。


现实中的“四大怪象”

如果你仔细观察身边的技术团队,朋友圈或者审视一下自己,可能就会发现我们都在不自觉地陷入以下误区:

怪象一:技术洁癖引发的“伪精英心态”

很多人认为依赖工具是能力退化的表现。他们以“纯手工打造”为荣,认为只有自己敲出来的代码/文字才叫硬核,用 AI 就像是“作弊”。

怪象二:工具依赖导致的“思维躺平”

另一极端是,有了 AI 就不思考了。遇到问题直接扔给 AI,AI 给什么就用什么,不再去探究底层的原理,甚至觉得“反正 AI 会,我不用学了”。

怪象三:盲目信任带来的“埋雷行为”

把 AI 当作真理的化身。直接 Copy & Paste AI 生成的代码上线,不看逻辑,不测边界,结果把 AI 的幻觉(Hallucination)直接变成了线上的 Bug。

怪象四:浅尝辄止的“低效勤奋”

虽然也在用 AI,但只停留在“帮我写个正则”、“解释这段代码”的浅层阶段。手里拿着加特林机关枪,却只把它当烧火棍用。


All in AI 之前的“四重认知突围”

针对上述怪象,如果想在 2025 年以及未来几年生存并晋级,我们需要进行一次彻底的认知重构。

认知 1:拒绝羞耻感 —— 它是“外骨骼”,不是“轮椅”

(对标怪象一)

越是基本功扎实的老兵,越容易有“技术羞耻感”。请立刻抛弃这种旧思维。

在 2025 年,能力定义的公式变了

  • 旧能力 = 记忆力 + 手速 + 经验
  • 新能力 = (经验 + 洞察) × AI 算力

使用 AI 不是因为你“能力不行”需要轮椅,而是为了放大你的能力。它让你从繁琐的语法/文书细节(Syntax)中解脱出来,让你的架构设计能力得以十倍级释放。善用“机关枪”是特种兵的素养,不是逃兵的借口。

认知 2:拒绝躺平 —— 是“升维”,不是“减负”

(对标怪象二)

以为用了 AI 就可以不学习了?大错特错。

AI 时代的学习逻辑发生了倒置: AI 负责“已知知识的检索与生成”,你负责“未知领域的洞察与判断”。

当 AI 帮你搞定了 80% 的“实现细节(How)”,你必须把节省下来的精力,投入到那 20% 更核心的“价值判断(Why & What)”中。

你不仅不能停止学习,反而要学得更深、更广——否则你甚至不知道该如何向 AI 提问,更不知道如何判断它给出的方案是平庸还是卓越。

认知 3:坚守底线 —— 做“机长”,不做“乘客”

(对标怪象三)

AI 的第一性原理(概率预测)决定了它永远存在“一本正经胡说八道”的可能。

对 AI 输出的成果物进行严苛的审核 (Review),是任何成果物发布前的必经路径。

你需要从“Writer(撰稿人)”转型为“Editor-in-Chief(总编辑)”

你是机长,AI 是副驾驶。它负责操作仪表盘,但你负责决定航向,并对每一次降落的安全性负责。 没有审核的 AI 代码/文档,就是一颗定时炸弹。这意味着你不能只看代码跑通了没有,还要像审查实习生代码一样,去盘问它的逻辑漏洞和边缘情况。

认知 4:直面竞争 —— 比的是“枪法”,不是“有枪”

(对标怪象四)

三年过去,AI 已经祛魅。现在人人手里都有一把“机关枪”(Cursor, Claude Code, Copilot 等)。

竞争的维度变了:不再是谁有枪(因为大家都有),而是谁的枪法更准。

  • 初级枪法: 单轮对话,只会问简单问题。
  • 高级枪法: 懂得 Context Injection(上下文注入)、Chain of Thought(思维链)、Spec-Driven(规范驱动开发工作流)。

“都用 AI”只是入场券。 真正的比拼,在于谁用得更深、更精,谁能用这把枪打出“百步穿杨”的效果。


小结:是时候All in AI了!

技术历史的车轮滚滚向前,残酷性从未改变。

每一次技术范式的转移,都会留下一批抱残守缺的“大刀队”。他们不是不努力,他们甚至比谁都辛苦,每天挥舞大刀砍得汗流浃背,但在“机关枪”的扫射下,这种努力显得苍白无力。

2025 年末,放下你的大刀吧。

去学习怎么校准瞄准镜,怎么控制后坐力,怎么设计交叉火力网。这不丢人。这才是对技术、对自己职业生涯最大的尊重。


互动话题

在使用 AI 编程的过程中,你遇到过最让你“细思极恐”的时刻是什么?或者最让你感到“真香”的瞬间是什么?欢迎在留言区分享你的故事。


如何练就“百步穿杨”的枪法?

文章里我们说了,“都用 AI”只是入场券,真正的决胜点在于谁用得更深、更精,谁拥有一套高维度的“AI 原生工作流”

如果你已经决定放下“大刀”,拿起“机关枪”,但面对市面上眼花缭乱的工具(Claude Code, Cursor, Windsurf)和碎片化的技巧,感到无从下手;

或者你虽然用了 AI,但发现自己依然陷入在“改 Bug -> AI 生成新 Bug”的低效死循环中;

那么,欢迎加入我的极客时间专栏《AI 原生开发工作流实战》

在这里,我们将深入实战:

  • 重构开发范式: 彻底告别“聊天式编程”,掌握 SDD (规范驱动开发) 的核心心法,学会用 Spec 文档精准指挥 AI。
  • 驾驭 Agentic 系统: 深入剖析 Claude Code 等 Agentic Tools 的底层逻辑,把它们变成你忠实的“外包团队”。
  • 构建私有/团队工作流: 手把手教你搭建一套“人脑定义目标 + AI 并发执行”的高效流水线。

别让手里的机关枪生锈。 点击下方卡片,我们一起在实战中进化。


你的Go技能,是否也卡在了“熟练”到“精通”的瓶颈期?

  • 想写出更地道、更健壮的Go代码,却总在细节上踩坑?
  • 渴望提升软件设计能力,驾驭复杂Go项目却缺乏章法?
  • 想打造生产级的Go服务,却在工程化实践中屡屡受挫?

继《Go语言第一课》后,我的《Go语言进阶课》终于在极客时间与大家见面了!

我的全新极客时间专栏 《Tony Bai·Go语言进阶课》就是为这样的你量身打造!30+讲硬核内容,带你夯实语法认知,提升设计思维,锻造工程实践能力,更有实战项目串讲。

目标只有一个:助你完成从“Go熟练工”到“Go专家”的蜕变! 现在就加入,让你的Go技能再上一个新台阶!


商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求,请扫描下方公众号二维码,与我私信联系。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言进阶课 AI原生开发工作流实战 Go语言精进之路1 Go语言精进之路2 Go语言第一课 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats