<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tony Bai &#187; Cpp</title>
	<atom:link href="http://tonybai.com/tag/cpp/feed/" rel="self" type="application/rss+xml" />
	<link>https://tonybai.com</link>
	<description>一个程序员的心路历程</description>
	<lastBuildDate>Sat, 11 Apr 2026 00:16:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>告别古法编程黄金时代：AI 时代不会再有新编程语言诞生的土壤</title>
		<link>https://tonybai.com/2026/03/24/no-soil-for-new-programming-languages-in-ai-era/</link>
		<comments>https://tonybai.com/2026/03/24/no-soil-for-new-programming-languages-in-ai-era/#comments</comments>
		<pubDate>Mon, 23 Mar 2026 23:45:43 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[AgenticCoding]]></category>
		<category><![CDATA[AIProgramming]]></category>
		<category><![CDATA[AI编程]]></category>
		<category><![CDATA[AndrejKarpathy]]></category>
		<category><![CDATA[ArtificialIntelligence]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[ClaudeCode]]></category>
		<category><![CDATA[CodeGeneration]]></category>
		<category><![CDATA[CorpusHegemony]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[HandcraftedCode]]></category>
		<category><![CDATA[IntermediateRepresentation]]></category>
		<category><![CDATA[LLM]]></category>
		<category><![CDATA[NaturalLanguageProgramming]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[ProgrammingLanguages]]></category>
		<category><![CDATA[ProgrammingParadigm]]></category>
		<category><![CDATA[Prompt]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Rust]]></category>
		<category><![CDATA[Software3.0]]></category>
		<category><![CDATA[SoftwareEngineering]]></category>
		<category><![CDATA[SoftwareFactory]]></category>
		<category><![CDATA[spec]]></category>
		<category><![CDATA[TechEvolution]]></category>
		<category><![CDATA[中间码]]></category>
		<category><![CDATA[人工智能]]></category>
		<category><![CDATA[代码生成]]></category>
		<category><![CDATA[古法编程]]></category>
		<category><![CDATA[大模型]]></category>
		<category><![CDATA[技术演进]]></category>
		<category><![CDATA[提示词]]></category>
		<category><![CDATA[智能体编程]]></category>
		<category><![CDATA[编程范式]]></category>
		<category><![CDATA[编程语言]]></category>
		<category><![CDATA[自然语言编程]]></category>
		<category><![CDATA[规格说明书]]></category>
		<category><![CDATA[语料霸权]]></category>
		<category><![CDATA[软件工厂]]></category>
		<category><![CDATA[软件工程]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=6092</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2026/03/24/no-soil-for-new-programming-languages-in-ai-era 大家好，我是Tony Bai。 如果你回望过去十五年的软件工程史，那无疑是编程语言百花齐放的黄金时代。 为了对抗日益膨胀的系统复杂度，人类绞尽脑汁地发明新的“咒语”： Google 推出了 Go 语言，用极简的 Goroutine 拯救了深陷并发地狱的后端工程师； Mozilla 孕育了 Rust，用严苛的所有权机制向内存泄漏和数据竞争宣战； 苹果用 Swift 埋葬了晦涩的 Objective-C； JetBrains 用 Kotlin 为笨重的 Java的使用者提供了一个更优雅的选择； 微软用 TypeScript 彻底规范了狂野的 JavaScript 生态。 每一次新语言的诞生，都伴随着开发者们的狂欢。我们热衷于讨论语法糖、对比编译速度、争论哪种范式更优雅。我们在各大论坛上为自己喜爱的语言摇旗呐喊。 但这已经是最后的余晖了。 站在 2026 年的节点上，当你看着 Claude Code、Cursor 或各类 Coding Agent 在几秒钟内倾泻出数千行逻辑严密的代码时，一个残酷的真相正在浮出水面： 大模型（LLM）的爆发，彻底抽干了孕育下一代通用编程语言的土壤。属于人类的“造语言”游戏，结束了。 这不是危言耸听，而是基于技术演进第一性原理的必然推演。 语料霸权：新语言无法跨越的“生态死局” 在 AI 时代，一门编程语言的生命力不再取决于它的语法有多么优雅，而取决于它在 AI 模型中的“语料权重”。 现存的主流语言（Python, Java, JavaScript, Go, C/C++等）在 GitHub [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2026/no-soil-for-new-programming-languages-in-ai-era-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2026/03/24/no-soil-for-new-programming-languages-in-ai-era">本文永久链接</a> &#8211; https://tonybai.com/2026/03/24/no-soil-for-new-programming-languages-in-ai-era</p>
<p>大家好，我是Tony Bai。</p>
<p>如果你回望过去十五年的软件工程史，那无疑是编程语言百花齐放的黄金时代。</p>
<p>为了对抗日益膨胀的系统复杂度，人类绞尽脑汁地发明新的“咒语”：</p>
<p>Google 推出了 Go 语言，用极简的 Goroutine 拯救了深陷并发地狱的后端工程师；</p>
<p>Mozilla 孕育了 Rust，用严苛的所有权机制向内存泄漏和数据竞争宣战；</p>
<p>苹果用 Swift 埋葬了晦涩的 Objective-C；</p>
<p>JetBrains 用 Kotlin 为笨重的 Java的使用者提供了一个更优雅的选择；</p>
<p>微软用 TypeScript 彻底规范了狂野的 JavaScript 生态。</p>
<p>每一次新语言的诞生，都伴随着开发者们的狂欢。我们热衷于讨论语法糖、对比编译速度、争论哪种范式更优雅。我们在各大论坛上为自己喜爱的语言摇旗呐喊。</p>
<p><strong>但这已经是最后的余晖了。</strong></p>
<p>站在 2026 年的节点上，当你看着 <a href="http://gk.link/a/12EPd">Claude Code</a>、Cursor 或各类 Coding Agent 在几秒钟内倾泻出数千行逻辑严密的代码时，一个残酷的真相正在浮出水面：</p>
<p><strong>大模型（LLM）的爆发，彻底抽干了孕育下一代通用编程语言的土壤。属于人类的“造语言”游戏，结束了。</strong></p>
<p>这不是危言耸听，而是基于技术演进第一性原理的必然推演。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2026/agentic-software-engineering-qr.png" alt="" /></p>
<h2>语料霸权：新语言无法跨越的“生态死局”</h2>
<p>在 AI 时代，一门编程语言的生命力不再取决于它的语法有多么优雅，而取决于它在 AI 模型中的<strong>“语料权重”</strong>。</p>
<p>现存的主流语言（Python, Java, JavaScript, Go, C/C++等）在 GitHub 上积累了数年甚至十余年的海量开源代码。这些代码构成了大模型训练的底座，赋予了 AI 极高的“代码智商”。</p>
<p>当你用 Python 或 Go 提问时，AI 能够瞬间理解你的意图，补全复杂的逻辑，甚至自动发现隐藏的 Bug，因为它的“脑子”里装着上千万个成熟的 Python/Go 示例。</p>
<p><strong>但对于一门新语言来说，这是绝对的死局。</strong></p>
<p>假设明天某个天才发布了一门名为 Nova 的新语言，号称性能超越 C，安全性超越 Rust，语法如 Python 般简洁。</p>
<p>结果会怎样？</p>
<ul>
<li>AI 不会写：因为训练语料里没有 Nova 的代码，大模型对它一无所知，无法提供智能补全。</li>
<li>人类不会用：在“没有 AI 辅助就感觉不会写代码”的今天，一个习惯了口述意图，让AI Coding Agent 自动生成全量代码的程序员，绝不可能去碰一门必须纯手工敲击、AI 无法帮他编写和Debug的语言。</li>
</ul>
<p>这就形成了一个无解的<strong>马太效应</strong>：</p>
<pre><code>没人写就没有语料 -&gt; 没有语料 AI 就不会写 -&gt; AI 不会写人类就不想学 -&gt; 更没人写。
</code></pre>
<p><strong>现存的主流语言通过“语料霸权”，彻底锁死了新语言上升的通道。</strong></p>
<h2>需求降维：为什么我们不再需要“更好写”的语言？</h2>
<p>人类发明新语言的根本动力，是<strong>“人脑的带宽有限”</strong>。</p>
<p>C++ 太容易写出内存泄漏，人脑排查太痛苦，所以我们发明了 Rust，让编译器做“真理警察”。</p>
<p>Java 处理异步回调太繁琐（Callback Hell），所以我们发明了各种新的语法糖。</p>
<p>我们一直在努力打造更锋利、更安全的斧头，因为那是人类自己要挥舞的斧头。</p>
<p>但在 Agentic Coding（智能体编程）时代，挥舞斧头的不再是人，而是不知疲倦的 AI。</p>
<p>当你可以用自然语言对 Agent 说：<em>“用 C++ 实现一个高并发的 HTTP 服务器，并严格检查所有内存泄漏风险，写出 100% 覆盖率的测试用例。”</em></p>
<p>只要 AI 的推理能力足够强，加上自动化的沙箱验证（Eval），它完全可以写出极度安全、高效的 C++ 代码。</p>
<p>如果 AI 能够不知疲倦地处理最繁琐的语法、填补最冗长的样板代码（Boilerplate），并且不出错，那么“语言本身是否易读、是否好写” 似乎就变得不再重要了。</p>
<p>因为代码根本不是给人看的，也不是人写的。当“人脑带宽”不再是瓶颈，发明一种“让人类写得更舒服”的新语言，就失去了最大的现实动机。</p>
<h2>语言的两极化：自然语言与“AI 中间码”</h2>
<p>如果不再有新的面向人类的通用编程语言，未来的代码世界会变成什么样？</p>
<p>答案是：<strong>极端的两极分化。</strong></p>
<p><strong>上层：英语（或自然语言）成为终极编程语言。</strong></p>
<p>Andrej Karpathy 的预言正在成为现实（Software 3.0）。人类不需要学习晦涩的语法，人类只需要学习如何清晰、严谨地表达意图，编写能够精准约束 AI 的 <strong>Spec（规格说明书）</strong>。我们与机器的接口，退回到了人类最擅长的媒介。</p>
<p><strong>底层：只有机器能读懂的“AI 专属语言”。</strong></p>
<p>如果你是大模型厂商（比如 OpenAI 或 Google），当你发现 90% 的代码都是你的模型生成的，你还会让模型生成冗长、为了兼顾人类可读性而充满妥协的 Java 或 Python 代码吗？</p>
<p>不会的。巨头们极有可能会研发一种<strong>专门面向 AI 优化的中间表示语言（Intermediate Representation, IR）</strong>。</p>
<p>这种语言对人类来说如同天书，但对于模型来说：</p>
<ul>
<li>Token 效率极高：原本需要 1000 个 Token 表达的逻辑，这种语言只要 50 个 Token，极大节省推理成本和上下文窗口。</li>
<li>逻辑高度压缩：天生适合并行计算和智能体之间的状态传递。</li>
</ul>
<p>AI 会将人类的自然语言直接“编译”成这种中间码，然后运行。</p>
<p>在这个过程中，介于自然语言和机器码之间、那种专门为了“让人类勉强能懂又能让机器执行”而存在的传统编程语言，其生存空间将被彻底抽空。</p>
<h2>小结：致敬“古法编程”的黄金时代</h2>
<p><img src="https://tonybai.com/wp-content/uploads/2026/no-soil-for-new-programming-languages-in-ai-era-2.png" alt="" /></p>
<p>这听起来有些感伤，但这就是技术演进的无情车轮。</p>
<p>就像今天，依然有人沉迷于机械表的齿轮咬合，依然有人热爱在暗房里冲洗胶卷。</p>
<p><strong>“纯手工编写代码（Handcrafted Code）”</strong>——这种我们曾引以为傲的工业生产方式，未来可能也会退化成一种个人的“艺术爱好”或“思维体操”。我们称之为<strong>“古法编程”</strong>。</p>
<p>在某个安静的周末，你或许依然会打开编辑器，为了兴趣手撸一段优雅的 Go 并发或者 Rust 生命周期，享受那种久违的、直接控制机器的“心流”多巴胺。</p>
<p>但在残酷的商业战场上，古法编程即将落幕。</p>
<p>不要再为语法糖而争论不休，不要再期待下一个能拯救你的新语言。</p>
<p>去锻炼你的系统思维吧，去学着用自然语言精准地描绘你的蓝图。因为在下一个时代，<strong>定义目标的造物主，永远比精通语法的泥瓦匠更稀缺。</strong></p>
<hr />
<p><strong>你还在坚持“古法编程”吗？</strong></p>
<p>面对 AI 现场生成代码的冲击，你是否还会为了某种语言的“优雅语法”而兴奋？在你的理想中，未来的“AI 专用中间码”应该长什么样？你是更享受亲自掌控每一行代码，还是更向往定义目标的“造物主”角色？</p>
<p>欢迎在评论区留下你对“古法编程”时代的最后致敬！</p>
<hr />
<p>还在为“复制粘贴喂AI”而烦恼？我的新专栏 <strong>《<a href="http://gk.link/a/12EPd">AI原生开发工作流实战</a>》</strong> 将带你：</p>
<ul>
<li>告别低效，重塑开发范式</li>
<li>驾驭AI Agent(Claude Code)，实现工作流自动化</li>
<li>从“AI使用者”进化为规范驱动开发的“工作流指挥家”</li>
</ul>
<p>扫描下方二维码，开启你的AI原生开发之旅。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/ai-native-dev-workflow-qr.png" alt="" /></p>
<hr />
<p>你的Go技能，是否也卡在了“熟练”到“精通”的瓶颈期？</p>
<ul>
<li>想写出更地道、更健壮的Go代码，却总在细节上踩坑？</li>
<li>渴望提升软件设计能力，驾驭复杂Go项目却缺乏章法？</li>
<li>想打造生产级的Go服务，却在工程化实践中屡屡受挫？</li>
</ul>
<p>继《<a href="http://gk.link/a/10AVZ">Go语言第一课</a>》后，我的《<a href="http://gk.link/a/12yGY">Go语言进阶课</a>》终于在极客时间与大家见面了！</p>
<p>我的全新极客时间专栏 《<a href="http://gk.link/a/12yGY">Tony Bai·Go语言进阶课</a>》就是为这样的你量身打造！30+讲硬核内容，带你夯实语法认知，提升设计思维，锻造工程实践能力，更有实战项目串讲。</p>
<p>目标只有一个：助你完成从“Go熟练工”到“Go专家”的蜕变！ 现在就加入，让你的Go技能再上一个新台阶！</p>
<p><img src="https://tonybai.com/wp-content/uploads/course-card/iamtonybai-banner-2.gif" alt="" /></p>
<hr />
<p><strong>原「Gopher部落」已重装升级为「Go &amp; AI 精进营」知识星球，快来加入星球，开启你的技术跃迁之旅吧！</strong></p>
<p>我们致力于打造一个高品质的 <strong>Go 语言深度学习</strong> 与 <strong>AI 应用探索</strong> 平台。在这里，你将获得：</p>
<ul>
<li><strong>体系化 Go 核心进阶内容:</strong> 深入「Go原理课」、「Go进阶课」、「Go避坑课」等独家深度专栏，夯实你的 Go 内功。</li>
<li><strong>前沿 Go+AI 实战赋能:</strong> 紧跟时代步伐，学习「Go+AI应用实战」、「Agent开发实战课」、「Agentic软件工程课」、「Claude Code开发工作流实战课」、「OpenClaw实战分享」等，掌握 AI 时代新技能。 </li>
<li><strong>星主 Tony Bai 亲自答疑:</strong> 遇到难题？星主第一时间为你深度解析，扫清学习障碍。</li>
<li><strong>高活跃 Gopher 交流圈:</strong> 与众多优秀 Gopher 分享心得、讨论技术，碰撞思想火花。</li>
<li><strong>独家资源与内容首发:</strong> 技术文章、课程更新、精选资源，第一时间触达。</li>
</ul>
<p>衷心希望「Go &amp; AI 精进营」能成为你学习、进步、交流的港湾。让我们在此相聚，享受技术精进的快乐！欢迎你的加入！</p>
<p><img src="http://image.tonybai.com/img/tonybai/gopher-and-ai-tribe-zsxq-small-card.jpg" alt="img{512x368}" /></p>
<hr />
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求，请扫描下方公众号二维码，与我私信联系。</p>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p style='text-align:left'>&copy; 2026, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2026/03/24/no-soil-for-new-programming-languages-in-ai-era/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gopher直通大厂，就从这第一课开始！</title>
		<link>https://tonybai.com/2025/09/03/gopher-first-lesson-to-big-factory/</link>
		<comments>https://tonybai.com/2025/09/03/gopher-first-lesson-to-big-factory/#comments</comments>
		<pubDate>Wed, 03 Sep 2025 00:52:21 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Channel]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[CSP]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[go1兼容性]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[gomodule]]></category>
		<category><![CDATA[goroutine]]></category>
		<category><![CDATA[Go语言第一课]]></category>
		<category><![CDATA[k8s]]></category>
		<category><![CDATA[main]]></category>
		<category><![CDATA[Package]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[云服务]]></category>
		<category><![CDATA[包]]></category>
		<category><![CDATA[单元测试]]></category>
		<category><![CDATA[大厂]]></category>
		<category><![CDATA[字节跳动]]></category>
		<category><![CDATA[并发]]></category>
		<category><![CDATA[微信]]></category>
		<category><![CDATA[性能]]></category>
		<category><![CDATA[指针]]></category>
		<category><![CDATA[操作系统]]></category>
		<category><![CDATA[显式]]></category>
		<category><![CDATA[极客时间]]></category>
		<category><![CDATA[泛型]]></category>
		<category><![CDATA[测试]]></category>
		<category><![CDATA[测试覆盖率]]></category>
		<category><![CDATA[滴滴]]></category>
		<category><![CDATA[生产力]]></category>
		<category><![CDATA[简单]]></category>
		<category><![CDATA[类型参数]]></category>
		<category><![CDATA[类型约束]]></category>
		<category><![CDATA[组合]]></category>
		<category><![CDATA[腾讯]]></category>
		<category><![CDATA[阿里]]></category>
		<category><![CDATA[面向工程]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=5116</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/09/03/gopher-first-lesson-to-big-factory 大家好，我是Tony Bai。 很多计算机专业的同学们都在问：想进大厂，要先学好哪门编程语言？ 从应用广泛程度来说，学好Go语言肯定错不了！我们来看一下大厂们都用Go在做哪些开发： 阿里用于基础服务、网关、容器、服务框架等开发。 字节跳动用于即时通信（IM）、K8s、微服务等开发。 腾讯用于微信后台、云服务、游戏后端等开发。 滴滴用于数据平台、调度系统、消息中间件等开发。 此外，美团、百度、京东、小米等都在业务中大量使用Go语言做开发。可见，同学们只要玩转Go语言，大厂都会张开双臂欢迎你们。 大厂为何如此青睐Go语言呢？有三点重要原因： 简单易上手： Go语法简洁，学习成本低，代码易维护； 生产力与性能有效结合： Go拥有卓越的并发性能，内置调度器和非抢占式模型，保证了超高的稳定性； 使用快乐且前景广阔： 优良的开发体验，包括得心应手的工具链、丰富健壮的标准库、广泛的社区支持等。 总的来说，Go相对于C/C++，性能并没有明显差距，可维护性还更好；相对于Python，Go性能大幅领先，入门难度则相差无几。 直通大厂，同学们请看《Go 语言第一课》这本书，书中详细介绍了Go的设计哲学与核心理念，全面讲解了Go的重要语法特性。没有基础也完全不必担心，本书手把手式教学，小白立即轻松上手。 扫描上方二维码，即可五折购书(在有效期内) 现在，让我们进入课堂，开始Go语言学习的第一课吧。 Part.1 零基础起步，Go开发全掌握 本书为读者设计了一条循序渐进的学习路线，可以分为三个部分。 首先讲述Go语言的起源与设计哲学； 然后说明开发环境的搭建方法； 最后详细介绍Go的重要语法与语言特性，以及工程实施的一些细节。 初次学习Go开发的同学们一定要注意，动手实践是学习编程的不二法门，在进入第二部分学习时，就要根据书中内容同步搭建实验环境，一步一个脚印地走稳走好。 Go的设计哲学 本部分先介绍了Go语言在谷歌公司内部孵化的过程，描述了其在当今云计算时代的广泛应用。 Go的第一版官网 重点说明了Go的5个核心设计哲学： 简单： 仅有25个关键字，摒弃了诸多复杂的特性，便于快速上手； 显式： 要求代码逻辑清晰明确，避免隐式处理带来的不确定性； 组合： 通过类型嵌入提供垂直扩展能力，通过接口实现水平组合，灵活扩展功能； 并发： 原生支持并发，用户层轻量级线程，轻松支持高并发访问； 面向工程： 注重解决实际问题，围绕Go的库、工具、惯用法和软件工程方法，都为开发提供全面支持。 读者理解了Go的设计哲学就能明确它擅长的方向，澄清心中的疑问，也掌握了使用Go进行编程的指导原则。 Part.2 搭建Go开发环境 这部分先针对Windows、macOS、Linux三种主流操作系统给出了多种安装方法，包括使用安装包、使用预编译二进制包、通过源码编译，说明如何管理多个Go版本。 然后基于经典的“Hello World”示例，演示编译运行的方法，讲解Go的基本程序结构，包括包声明、导入包、main函数等内容。接着深入讲解Go包的定义、导入、初始化与编译单元。 // ch3/helloworld/main.go package main [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2025/gopher-first-lesson-to-big-factory-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/09/03/gopher-first-lesson-to-big-factory">本文永久链接</a> &#8211; https://tonybai.com/2025/09/03/gopher-first-lesson-to-big-factory</p>
<p>大家好，我是Tony Bai。</p>
<p>很多计算机专业的同学们都在问：想进大厂，要先学好哪门编程语言？</p>
<p>从应用广泛程度来说，学好Go语言肯定错不了！我们来看一下大厂们都用Go在做哪些开发：</p>
<blockquote>
<p>阿里用于基础服务、网关、容器、服务框架等开发。</p>
<p>字节跳动用于即时通信（IM）、K8s、微服务等开发。</p>
<p>腾讯用于微信后台、云服务、游戏后端等开发。</p>
<p>滴滴用于数据平台、调度系统、消息中间件等开发。</p>
</blockquote>
<p>此外，美团、百度、京东、小米等都在业务中大量使用Go语言做开发。可见，同学们只要玩转Go语言，大厂都会张开双臂欢迎你们。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/gopher-first-lesson-to-big-factory-2.png" alt="" /></p>
<p>大厂为何如此青睐Go语言呢？有三点重要原因：</p>
<ul>
<li><strong>简单易上手：</strong> Go语法简洁，学习成本低，代码易维护；</li>
<li><strong>生产力与性能有效结合：</strong> Go拥有卓越的并发性能，内置调度器和非抢占式模型，保证了超高的稳定性；</li>
<li><strong>使用快乐且前景广阔：</strong> 优良的开发体验，包括得心应手的工具链、丰富健壮的标准库、广泛的社区支持等。</li>
</ul>
<p>总的来说，Go相对于C/C++，性能并没有明显差距，可维护性还更好；相对于Python，Go性能大幅领先，入门难度则相差无几。</p>
<p>直通大厂，同学们请看《<a href="https://book.douban.com/subject/37499496/">Go 语言第一课</a>》这本书，书中详细介绍了Go的设计哲学与核心理念，全面讲解了Go的重要语法特性。没有基础也完全不必担心，本书手把手式教学，小白立即轻松上手。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/go-primer-published-4.png" alt="" /><br />
<center>扫描上方二维码，即可五折购书(在有效期内)</center></p>
<hr />
<p>现在，让我们进入课堂，开始Go语言学习的第一课吧。</p>
<h2>Part.1 零基础起步，Go开发全掌握</h2>
<p>本书为读者设计了一条循序渐进的学习路线，可以分为三个部分。</p>
<p>首先讲述Go语言的起源与设计哲学；</p>
<p>然后说明开发环境的搭建方法；</p>
<p>最后详细介绍Go的重要语法与语言特性，以及工程实施的一些细节。</p>
<p>初次学习Go开发的同学们一定要注意，动手实践是学习编程的不二法门，在进入第二部分学习时，就要根据书中内容同步搭建实验环境，一步一个脚印地走稳走好。</p>
<h3>Go的设计哲学</h3>
<p>本部分先介绍了Go语言在谷歌公司内部孵化的过程，描述了其在当今云计算时代的广泛应用。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/gopher-first-lesson-to-big-factory-3.png" alt="" /><br />
<center>Go的第一版官网</center></p>
<p>重点说明了Go的5个核心设计哲学：</p>
<ul>
<li><strong>简单：</strong> 仅有25个关键字，摒弃了诸多复杂的特性，便于快速上手；</li>
<li><strong>显式：</strong> 要求代码逻辑清晰明确，避免隐式处理带来的不确定性；</li>
<li><strong>组合：</strong> 通过类型嵌入提供垂直扩展能力，通过接口实现水平组合，灵活扩展功能；</li>
<li><strong>并发：</strong> 原生支持并发，用户层轻量级线程，轻松支持高并发访问；</li>
<li><strong>面向工程：</strong> 注重解决实际问题，围绕Go的库、工具、惯用法和软件工程方法，都为开发提供全面支持。</li>
</ul>
<p>读者理解了Go的设计哲学就能明确它擅长的方向，澄清心中的疑问，也掌握了使用Go进行编程的指导原则。</p>
<h2>Part.2 搭建Go开发环境</h2>
<p>这部分先针对Windows、macOS、Linux三种主流操作系统给出了多种安装方法，包括使用安装包、使用预编译二进制包、通过源码编译，说明如何管理多个Go版本。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/gopher-first-lesson-to-big-factory-4.png" alt="" /></p>
<p>然后基于经典的“Hello World”示例，演示编译运行的方法，讲解Go的基本程序结构，包括包声明、导入包、main函数等内容。接着深入讲解Go包的定义、导入、初始化与编译单元。</p>
<pre><code class="go">// ch3/helloworld/main.go
package main
import "fmt"
func main() {
    fmt.Println("hello, world")
}
</code></pre>
<p>详细讲解Go Module的核心概念，结合创世项目案例、社区共识、官方指南，给出清晰的项目布局建议。梳理了Go依赖管理的演化历程，重点讲解基于Go Module的依赖管理操作，包括添加、升级/降级、移除、替换等操作。</p>
<p>经过这部分的学习，读者可以掌握Go的编译与运行方法、项目的组织与管理，具备工程化的能力。</p>
<h2>Part.3 Go语言特性详解</h2>
<p>这部分是本书的重点，覆盖基础语法知识、并发、泛型、测试等内容；在结构上由浅入深，层层递进，读者只要坚持学练结合，就能全盘掌握Go的关键知识。</p>
<p>基础语法知识包含以下内容：</p>
<ul>
<li><strong>变量与类型：</strong> 说明变量的声明方法、变量的作用域。</li>
<li><strong>基本数据类型：</strong> 详细讲解布尔型、数值型、字符串型的特性与常用操作。</li>
<li><strong>常量：</strong> 重点讲解Go常量的创新性设计，包括无类型常量、隐式转换、实现枚举。</li>
<li><strong>复合数据类型：</strong> 讲解数组、切片、map类型、结构体的声明与操作。</li>
<li><strong>指针类型：</strong> 解释指针的概念，说明其用途与使用限制。</li>
<li><strong>控制结构：</strong> 详细介绍if、for、switch语句的用法，实现分支、循环功能。</li>
<li><strong>函数：</strong> 说明函数的声明、参数、多返回值特性，以及defer的使用与注意事项。</li>
<li><strong>错误处理：</strong> 讲解了error接口的错误处理，以及异常处理的panic机制。</li>
<li><strong>方法：</strong> 详解Go方法的声明与本质，通过类型嵌入模拟“实现继承”。</li>
<li><strong>接口：</strong> 说明接口类型的定义、实现方法与注意事项。</li>
</ul>
<p>并发是Go的“杀手锏”级高阶特性，书中详述了Go并发的原理，给出了并发实现方案，即通过channel通信实现goroutine间同步，而非共享内存。说明channel与select结合使用的惯用法。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/gopher-first-lesson-to-big-factory-5.png" alt="" /><br />
<center>CSP模型</center></p>
<p>泛型是Go 1.18版本的新增特性，解决了为不同类型编写重复代码的痛点。书中介绍了Go泛型设计演化简史，讲解泛型语法、类型参数、类型约束，并给出了代码示例。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/gopher-first-lesson-to-big-factory-6.png" alt="" /><br />
<center>接口类型的扩展定义</center></p>
<p>最后讨论Go代码的质量保障方法，介绍了Go内置的测试框架，包括单元测试、示例测试、测试覆盖率以及性能基准测试，帮助读者快速且方便地组织、编写、执行测试，并得到详尽的测试结果反馈。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/gopher-first-lesson-to-big-factory-7.png" alt="" /><br />
<center>Go测试覆盖率报告</center></p>
<h2>Part.4 作者介绍</h2>
<p><img src="https://tonybai.com/wp-content/uploads/2025/gopher-first-lesson-to-big-factory-8.png" alt="" /></p>
<p>本书作者Tony Bai（白明），资深架构师，行业经验超20年，现于汽车行业某独角兽Tier1企业担任车云平台架构组技术负责人。</p>
<p>出于对技术的追求与热爱，他发起了Gopher部落技术社群，也是tonybai.com的博主。</p>
<p>Tony Bai老师早在2011年Go语言还没发布Go 1.0稳定版本时，他就在跟随、实践。当Go在大规模生产环境中逐渐替代了C、Python，Go便成为他编写生产系统的第一语言。</p>
<p>后来，Tony Bai老师在极客时间上开设课程讲解Go语言开发，引领学员从入门到建立思维框架，走向大厂。累计2.4w名学员学习这门课程并纷纷给出高分评价。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/gopher-first-lesson-to-big-factory-9.png" alt="" /></p>
<p>如今，Tony Bai老师基于在线课程将内容整理成书，并补充了之前缺失的重要语法点（如指针、测试、泛型等），并对已有内容进行了精炼，同时更新至Go 1.24版本。</p>
<p>相信这本书会帮助更多读者轻松学会Go语言，解决实际工作问题，获得职业成功。</p>
<h2>Part.5 结语</h2>
<p>《Go 语言第一课》这本书可以说既懂新手痛点，又懂工程实战。本书从Go的设计哲学入手，然后给出保姆级的环境搭建、代码组织指南，最后通过由浅入深的语法讲解，覆盖从基础到高阶的所有核心特性。</p>
<p>本书具备三大特点。</p>
<p><strong>第一是高屋建翎</strong>，开篇即剖析Go语言的设计哲学和编程思想，帮助读者透彻理解Go的核心理念，了解Go的特长，知道如何使用以获得最佳效果。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/gopher-first-lesson-to-big-factory-10.png" alt="" /><br />
<center>精彩书摘</center></p>
<p><strong>第二是路径完整</strong>，覆盖Go入门的基础知识与概念，打通基础知识-语法特性-工程实践全流程，助力读者从新手进化为合格的Go开发工程师。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/gopher-first-lesson-to-big-factory-11.png" alt="" /><br />
<center>精彩书摘</center></p>
<p><strong>第三是保姆级讲解</strong>，搭建环境是一步一图，讲解语法时辅以大量精心设计的示例代码，简洁明了，帮助读者直观地理解和掌握重点与难点内容。书中还针对Go开发中易犯的错误给出了贴心的避坑提示。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/gopher-first-lesson-to-big-factory-12.png" alt="" /><br />
<center>精彩书摘</center></p>
<p>本书适合各个层次的读者。对于Go初学者，可以循序渐进地掌握Go编程；对于动态编程语言的开发者，可以通过本书平滑转投Go阵营；对于Go的技术爱好者，可以增进认知，培养专业开发水准。</p>
<p>现在翻开《Go 语言第一课》，开启Go开发之旅，高并发服务端、云原生应用开发，都将轻松掌控！</p>
<h2><strong>今日互动</strong></h2>
<p>说说你对Go语言的看法？</p>
<p>点击右侧链接，在<a href="https://mp.weixin.qq.com/s/pxIfuxtQN7HTXBxwYQMw3Q">原文留言区</a>参与互动，并点击在看和转发活动到朋友圈，我们将选1名读者获得赠书1本，截止时间9月15日。</p>
<hr />
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求，请扫描下方公众号二维码，与我私信联系。</p>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p style='text-align:left'>&copy; 2025, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2025/09/03/gopher-first-lesson-to-big-factory/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Go语言正在成为“老旧”生态的“新引擎”？从 FrankenPHP 和新版 TypeScript 编译器谈起</title>
		<link>https://tonybai.com/2025/08/06/go-new-engine-of-old-languages/</link>
		<comments>https://tonybai.com/2025/08/06/go-new-engine-of-old-languages/#comments</comments>
		<pubDate>Wed, 06 Aug 2025 00:09:10 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[fpm]]></category>
		<category><![CDATA[FrankenPHP]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[Gopher]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[supervisor]]></category>
		<category><![CDATA[TS]]></category>
		<category><![CDATA[TypeScript]]></category>
		<category><![CDATA[typescript-go]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=5001</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/08/06/go-new-engine-of-old-languages 大家好，我是Tony Bai。 我先来描述一种编程语言生态，请你猜猜它是谁： 它诞生于 1995 年，旨在为当时一个叫“万维网”的新平台构建应用。起初只是个小项目，却在互联网泡沫中野蛮生长，成为史上用户最广的语言之一。它曾被“严肃”的程序员们嘲笑了几十年，但最终得到了科技巨头的加持，迎来了事业的第二春。如今，它正迈向 30 岁，而其生态中最重要的一环——它的一个超集语言的编译器，正在被 Go 语言 重写以驱动未来。 你的第一反应，很可能是 JavaScript 生态。完全正确。这个超集语言，就是 TypeScript。 但这段描述，同样完美地适用于另一个名字：PHP。它也诞生于 1995 年，同样在 Web 浪潮中崛起，同样被嘲笑，同样迎来了第二春，而现在，一个基于 Go 语言 的新项目，也正在驱动着它的未来。 这两种语言，就像是同一枚硬币的两面，共同定义了 Web 编程的客户端与服务器端。而今天，我想和你聊的，正是它们故事中那个令人意想不到的、与我们 Gopher 息息相关的交集——Go 语言的角色。 编程语言中的“丰田卡罗拉” 在深入主题之前，我们必须先理解 PHP 的生态位。一篇精彩的博文将其比作编程语言中的“丰田卡罗拉”——无聊、坚固、简单、实惠。 它或许永远不会出现在技术发布会最酷炫的 Demo 上，但它和它经典的 LAMP（Linux, Apache, MySQL, PHP）组合，让全世界数以百万计的普通开发者，能以最低的成本、最可靠的方式，解决一个最实际的问题：搭建一个能用的网站。 C++ 的创造者 Bjarne Stroustrup 有一句名言：“世界上只有两种语言：一种是被人拼命吐槽的，另一种是没人用的。” PHP 显然属于前者。它曾被嘲笑为“糟糕设计的集合体”，但它也支撑着全球 70% 以上的网站。这个数字，无论你用何种挑剔的眼光审视，都无法否认其巨大的成功和顽强的生命力。 Go：一个意想不到的“新引擎” 多年以来，PHP 和 [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2025/go-new-engine-of-old-languages-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/08/06/go-new-engine-of-old-languages">本文永久链接</a> &#8211; https://tonybai.com/2025/08/06/go-new-engine-of-old-languages</p>
<p>大家好，我是Tony Bai。</p>
<p>我先来描述一种编程语言生态，请你猜猜它是谁：</p>
<blockquote>
<p>它诞生于 1995 年，旨在为当时一个叫“万维网”的新平台构建应用。起初只是个小项目，却在互联网泡沫中野蛮生长，成为史上用户最广的语言之一。它曾被“严肃”的程序员们嘲笑了几十年，但最终得到了科技巨头的加持，迎来了事业的第二春。如今，它正迈向 30 岁，而其生态中最重要的一环——它的一个超集语言的编译器，正在被 <strong>Go 语言</strong> 重写以驱动未来。</p>
</blockquote>
<p>你的第一反应，很可能是 <strong>JavaScript</strong> 生态。完全正确。这个超集语言，就是 TypeScript。</p>
<p>但这段描述，同样完美地适用于另一个名字：<strong>PHP</strong>。它也诞生于 1995 年，同样在 Web 浪潮中崛起，同样被嘲笑，同样迎来了第二春，而现在，一个基于 <strong>Go 语言</strong> 的新项目，也正在驱动着它的未来。</p>
<p>这两种语言，就像是同一枚硬币的两面，共同定义了 Web 编程的客户端与服务器端。而今天，我想和你聊的，正是它们故事中那个令人意想不到的、与我们 Gopher 息息相关的交集——Go 语言的角色。</p>
<h2>编程语言中的“丰田卡罗拉”</h2>
<p>在深入主题之前，我们必须先理解 PHP 的生态位。<a href="https://deprogrammaticaipsum.com/the-toyota-corolla-of-programming/">一篇精彩的博文</a>将其比作<strong>编程语言中的“丰田卡罗拉”——无聊、坚固、简单、实惠。</strong></p>
<p>它或许永远不会出现在技术发布会最酷炫的 Demo 上，但它和它经典的 LAMP（Linux, Apache, MySQL, PHP）组合，让全世界数以百万计的普通开发者，能以最低的成本、最可靠的方式，解决一个最实际的问题：搭建一个能用的网站。</p>
<p>C++ 的创造者 Bjarne Stroustrup 有一句名言：“世界上只有两种语言：一种是被人拼命吐槽的，另一种是没人用的。”</p>
<p>PHP 显然属于前者。它曾被嘲笑为“糟糕设计的集合体”，但它也支撑着全球 70% 以上的网站。这个数字，无论你用何种挑剔的眼光审视，都无法否认其巨大的成功和顽强的生命力。</p>
<h2>Go：一个意想不到的“新引擎”</h2>
<p>多年以来，PHP 和 JavaScript 这两个庞大的生态，在各自的轨道上独立演进。但最近，一个令人瞩目的趋势正在浮现：<strong>Go 语言，正在成为驱动这两个“老旧”生态进行现代化改造的“新引擎”。</strong></p>
<p><strong>案例一：FrankenPHP &#8211; 用 Go 为 PHP “换心”</strong></p>
<p>如果你经历过在容器时代部署 PHP 应用的痛苦，你一定对 Nginx + FPM + Supervisor 这套复杂而脆弱的“三件套”记忆犹新。配置繁琐、性能瓶颈、进程管理困难，每一个都是噩梦。</p>
<p>现在，<strong>FrankenPHP</strong> 出现了。这是一个用 Go 语言编写的、全新的、高性能的 PHP 应用服务器，<a href="https://thephp.foundation/blog/2025/06/08/php-30/">最近已被 PHP 基金会正式采纳</a>。</p>
<p>它的革命性在于：</p>
<ol>
<li><strong>部署极简</strong>：它是一个<strong>单一的静态 Go 二进制文件</strong>。部署一个 PHP 应用，现在只需要一个包含这个二进制文件和你的 PHP 代码的、极其简单的 Dockerfile。Nginx, FPM, Supervisor 通通被扔进了历史的垃圾堆。</li>
<li><strong>性能卓越</strong>：它内置了一个基于 Caddy（另一个伟大的 Go 项目）的高性能 HTTP 服务器，并提供了全新的执行模型，性能远超传统模式。</li>
<li><strong>能力强大</strong>：Go 强大的并发能力和成熟的网络库，让 FrankenPHP 天生具备了现代应用服务器所需的一切。</li>
</ol>
<p>是 Go 语言，以一种釜底抽薪的方式，解决了 PHP 生态在云原生时代最大的部署和运维难题。</p>
<p><strong>案例二：新版 TypeScript 编译器 &#8211; 用 Go 提速</strong></p>
<p>无独有偶，在 Web 的另一端，JavaScript 生态也迎来了 Go 语言的赋能。微软最近宣布了一个激动人心的项目：用 <a href="https://tonybai.com/2025/03/13/interview-with-anders-hejlsberg">Go 语言来重写 TypeScript 编译器</a>。</p>
<p>TypeScript 作为 JavaScript 的超集，已经成为构建大型、复杂前端和后端应用的事实标准。它的编译器，是整个生态中至关重要的基础设施。</p>
<p>为什么选择 Go？答案同样简单而直接：<strong>性能</strong>，<a href="https://tonybai.com/2025/03/13/interview-with-anders-hejlsberg">当然也有其他一些考虑</a>。</p>
<p>编译器本质上是极其消耗 CPU 的密集型任务。随着 TypeScript 项目日益庞大和复杂，原有的编译器性能逐渐成为瓶颈。而 Go 语言，凭借其接近 C/C++ 的运行效率、卓越的并发模型以及内存安全保证，成为了构建下一代高性能编译器的理想选择。</p>
<h2>Go 语言的新角色：从“建新城”到“改旧都”</h2>
<p>这两个案例，揭示了 Go 语言一个正在崛起的新角色。</p>
<p>过去，我们谈论 Go，更多的是用它来<strong>构建全新的云原生微服务</strong>——我们用它在一片空地上“建新城”。但现在，我们看到，Go 凭借其三大核心优势，正在成为<strong>改造和赋能现有庞大技术生态的“基础设施底座”</strong>。我们开始用它来“改造旧都”。</p>
<p>这三大优势是：</p>
<ol>
<li><strong>极致的性能</strong>：对于需要压榨性能的系统工具（如编译器、服务器），Go 提供了一个远比 C/C++ 更安全、更具生产力的选择。</li>
<li><strong>无与伦比的部署简便性</strong>：静态链接的单一二进制文件，是为容器和 DevOps 时代而生的“终极交付物”。</li>
<li><strong>现代化的并发模型</strong>：Goroutine 和 Channel，为解决现代软件中无处不在的并发问题，提供了最优雅、最高效的语言级方案。</li>
</ol>
<p>Go 语言，正在从一个单纯的应用开发语言，下沉为更底层的、为其他生态提供核心动力的“引擎层”。</p>
<h2>结论：拥抱务实，而非追逐光环</h2>
<p>PHP 的故事，以及它与 Go 的这段奇妙姻缘，带给我们最深刻的启示，是一种超越语言之争的<strong>工程实用主义精神</strong>。</p>
<p>真正的技术进步，不仅仅在于创造全新的、闪闪发光的东西，更在于用更强大的工具，去务实地优化、改造和盘活那些已经支撑着世界运转的庞大系统。这是一种更深沉、更具影响力的贡献。</p>
<p>而 Go 语言，正在这个伟大的进程中，扮演着越来越重要的角色。作为 Gopher，我们不仅在“建新城”，我们也在为这个数字世界的“旧都”，换上一个更强劲、更可靠的“新引擎”。这，或许是 Go 语言未来最激动人心的篇章之一。</p>
<p>资料链接：https://deprogrammaticaipsum.com/the-toyota-corolla-of-programming/</p>
<hr />
<p>你的Go技能，是否也卡在了“熟练”到“精通”的瓶颈期？</p>
<ul>
<li>想写出更地道、更健壮的Go代码，却总在细节上踩坑？</li>
<li>渴望提升软件设计能力，驾驭复杂Go项目却缺乏章法？</li>
<li>想打造生产级的Go服务，却在工程化实践中屡屡受挫？</li>
</ul>
<p>继《<a href="http://gk.link/a/10AVZ">Go语言第一课</a>》后，我的《<a href="http://gk.link/a/12yGY">Go语言进阶课</a>》终于在极客时间与大家见面了！</p>
<p>我的全新极客时间专栏 《<a href="http://gk.link/a/12yGY">Tony Bai·Go语言进阶课</a>》就是为这样的你量身打造！30+讲硬核内容，带你夯实语法认知，提升设计思维，锻造工程实践能力，更有实战项目串讲。</p>
<p>目标只有一个：助你完成从“Go熟练工”到“Go专家”的蜕变！ 现在就加入，让你的Go技能再上一个新台阶！</p>
<p><img src="https://tonybai.com/wp-content/uploads/course-card/iamtonybai-banner-2.gif" alt="" /></p>
<hr />
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求，请扫描下方公众号二维码，与我私信联系。</p>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p style='text-align:left'>&copy; 2025, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2025/08/06/go-new-engine-of-old-languages/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Go vs. Rust vs. C++：从语言规范长度看三种不同的“复杂性”</title>
		<link>https://tonybai.com/2025/07/25/go-vs-rust-vs-cpp-in-complexity/</link>
		<comments>https://tonybai.com/2025/07/25/go-vs-rust-vs-cpp-in-complexity/#comments</comments>
		<pubDate>Fri, 25 Jul 2025 00:05:20 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[Agentic]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[BorrowChecker]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Channel]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[goroutine]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[lifetimes]]></category>
		<category><![CDATA[LLM]]></category>
		<category><![CDATA[ownership]]></category>
		<category><![CDATA[Rust]]></category>
		<category><![CDATA[style]]></category>
		<category><![CDATA[借用检查器]]></category>
		<category><![CDATA[所有权]]></category>
		<category><![CDATA[操作符重载]]></category>
		<category><![CDATA[模板]]></category>
		<category><![CDATA[泛型]]></category>
		<category><![CDATA[生命周期]]></category>
		<category><![CDATA[继承]]></category>
		<category><![CDATA[认知负荷]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=4948</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/07/25/go-vs-rust-vs-cpp-in-complexity) 大家好，我是Tony Bai。 最近，一张关于编程语言规范词数统计的图表，在技术圈广为流传。它以一种极其直观、甚至有些残酷的方式，将不同语言的复杂性摆在了我们面前。 在这张图上，我们看到了惊人的差异： C++: 以超过 80 万词的规范长度，一骑绝尘，成为当之无愧的“巨无霸”。 C# 和 Java: 分别以约 40 万和 25 万词紧随其后，是功能丰富的“航空母舰”。 Go: 规范仅约 5 万词，与以简洁著称的 C (约 5.5 万词) 处于同一量级。 这张图不仅仅是一个有趣的谈资。语言规范的长度，是衡量一门语言复杂度的最客观指标之一。 它直接决定了这门语言的学习曲线、认知负荷，以及整个生态的风格。 今天，我们就以这张图为起点，深入探讨三门备受关注的系统级语言——Go、Rust 和 C++——它们各自代表的三种截然不同的“复杂性”，以及这些“复杂性”在 AI 时代意味着什么。 注：Go之所以被最初定位为系统级编程语言，是因为其设计之初便承载了构建高效、可靠系统级软件的愿景，旨在解决多核、网络化机器时代下大型代码库的开发痛点。 然而，其内置的垃圾回收机制和相对较大的运行时， 以及它在网络服务、云计算、微服务等应用层领域取得的显著成功和广泛应用， 逐渐改变了开发者对其的普遍认知，使得今天多数开发者不再将其归类为传统的、如C/C++般直接操作硬件的系统级编程语言。 “广度”的复杂性：C++ 的特性博物馆 C++ 的冗长规范，源于其“广度”上的复杂性。它像一个不断扩建的“特性博物馆”，收藏了自上世纪 80 年代以来的几乎所有编程范式。从 C with Classes，到面向对象，再到泛型元编程，再到现代的函数式风格，C++ 不断地累加新特性，却很少移除旧的。 这种复杂性的特点是： 特性极其繁多： 多重继承、模板、操作符重载、右值引用&#8230; 你永远无法完全掌握它。 选择极其自由： 对于同一个问题，你可能有十种不同的实现方式，每一种都有其微妙的优劣。 [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2025/go-vs-rust-vs-cpp-in-complexity-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/07/25/go-vs-rust-vs-cpp-in-complexity">本文永久链接</a> &#8211; https://tonybai.com/2025/07/25/go-vs-rust-vs-cpp-in-complexity)</p>
<p>大家好，我是Tony Bai。</p>
<p>最近，一张关于编程语言规范词数统计的图表，在技术圈广为流传。它以一种极其直观、甚至有些残酷的方式，将不同语言的复杂性摆在了我们面前。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/go-vs-rust-vs-cpp-in-complexity-2.png" alt="" /></p>
<p>在这张图上，我们看到了惊人的差异：</p>
<ul>
<li><strong>C++:</strong> 以超过 80 万词的规范长度，一骑绝尘，成为当之无愧的“巨无霸”。</li>
<li><strong>C# 和 Java:</strong> 分别以约 40 万和 25 万词紧随其后，是功能丰富的“航空母舰”。</li>
<li><strong>Go:</strong> 规范仅约 5 万词，与以简洁著称的 C (约 5.5 万词) 处于同一量级。</li>
</ul>
<p>这张图不仅仅是一个有趣的谈资。<strong>语言规范的长度，是衡量一门语言复杂度的最客观指标之一。</strong> 它直接决定了这门语言的学习曲线、认知负荷，以及整个生态的风格。</p>
<p>今天，我们就以这张图为起点，深入探讨三门备受关注的系统级语言——Go、Rust 和 C++——它们各自代表的三种截然不同的“复杂性”，以及这些“复杂性”在 AI 时代意味着什么。</p>
<blockquote>
<p>注：<a href="https://tonybai.com/2025/07/03/meet-the-go-team-2012">Go之所以被最初定位为系统级编程语言</a>，是因为其设计之初便承载了构建高效、可靠系统级软件的愿景，旨在解决多核、网络化机器时代下大型代码库的开发痛点。 然而，其内置的垃圾回收机制和相对较大的运行时， 以及它在网络服务、云计算、微服务等应用层领域取得的显著成功和广泛应用， 逐渐改变了开发者对其的普遍认知，使得今天多数开发者不再将其归类为传统的、如C/C++般直接操作硬件的系统级编程语言。</p>
</blockquote>
<h2>“广度”的复杂性：C++ 的特性博物馆</h2>
<p>C++ 的冗长规范，源于其“广度”上的复杂性。它像一个不断扩建的“特性博物馆”，收藏了自上世纪 80 年代以来的几乎所有编程范式。从 C with Classes，到面向对象，再到泛型元编程，再到现代的函数式风格，C++ 不断地累加新特性，却很少移除旧的。</p>
<p>这种复杂性的特点是：</p>
<ul>
<li><strong>特性极其繁多：</strong> 多重继承、模板、操作符重载、右值引用&#8230; 你永远无法完全掌握它。</li>
<li><strong>选择极其自由：</strong> 对于同一个问题，你可能有十种不同的实现方式，每一种都有其微妙的优劣。</li>
</ul>
<p>这导致的结果是，没有人能成为一个“纯粹的 C++ 开发者”，大家通常都只是某个 C++“安全子集”的专家。团队协作的巨大成本，就耗费在统一这个“子集”上。Google 著名的 <a href="https://google.github.io/styleguide/cppguide.html">C++ Style Guide</a>，其本质就是一份“C++ 禁用特性列表”。</p>
<h2>“深度”的复杂性：Rust 的陡峭山峰</h2>
<p>再看 Rust。它的规范词数（约 10 万词）远比 C++ 短小，但几乎所有人都承认，Rust 的学习曲线极其陡峭。</p>
<p>这是因为它代表了另一种“深度”上的复杂性。Rust 的复杂性并非源于海量的特性，而是集中在少数几个强大、深刻且深度交织的核心概念上：</p>
<ul>
<li><strong>所有权 (Ownership)</strong></li>
<li><strong>生命周期 (Lifetimes)</strong></li>
<li><strong>借用检查器 (Borrow Checker)</strong></li>
</ul>
<p>你不需要学习一百个小工具，但你必须彻底攀登这几座陡峭的山峰，才能真正驾驭这门语言。它的挑战不在于“知道什么”，而在于“深刻理解”。你需要在脑海中构建一个全新的心智模型，时刻与编译器进行一场关于内存安全的“博弈”。</p>
<h2>“组合”的复杂性：Go 的乐高世界</h2>
<p>最后，我们来看 Go。它的规范如此之短，是因为它从设计之初就选择了第三条路：<strong>将“复杂性”从语言本身，转移到开发者身上。</strong></p>
<p>这里所说的Go的复杂性，是“组合”的复杂性。它为你提供的不是一套功能完备的“瑞士军刀”，而是一盒简单、正交、数量有限的“乐高积木”：</p>
<ul>
<li>简单的类型系统（没有类和继承）</li>
<li>只有一个循环结构 (for)</li>
<li>清晰的接口（隐式实现）</li>
<li>强大的并发原语 (goroutine 和 channel)</li>
<li>&#8230; &#8230;</li>
</ul>
<p>Go 语言本身是极其简单的，一个有经验的开发者可以在一周内掌握其全部语法。<strong>真正的挑战在于，你如何用这些有限的、简单的积木，去创造性地组合，以解决现实世界中的复杂问题。</strong></p>
<p>Go 的设计哲学相信，通过组合这些简单的工具，你足以构建出任何复杂的系统。它把对创造力的要求还给了开发者，而不是将其隐藏在语言的“语法糖”和“黑魔法”之下。</p>
<h2>AI 时代的新视角：哪种复杂性对 AI 更“友好”？</h2>
<p>这场关于复杂性的讨论，在 AI 编程助手日益普及的今天，有了一层全新的意义。我们可以把语言规范的长度，看作是教一个 AI“学生”这门语言的“教科书厚度”。</p>
<ul>
<li>
<p><strong>教 AI 写 C++：</strong> 就像给它一本大英百科全书。它能学会无数语法，但面对复杂的特性交互和未定义行为时，极易产生“幻觉”，生成看似正确但存在隐蔽 bug 的代码。<strong>审查这样的代码是一场噩梦。</strong></p>
</li>
<li>
<p><strong>教 AI 写 Rust：</strong> 就像教它下围棋。它能学会规则，但很难掌握其深奥的战略（生命周期）。它生成的代码或许能通过编译，但可能是为了“讨好”编译器而写出的、极其扭曲和不符合人类直觉的代码。</p>
</li>
<li>
<p><strong>教 AI 写 Go：</strong> 就像给它一本清晰、简洁的“小红书”。规则少、边界清晰、没有“魔法”。AI 生成的代码不仅更可预测、更符合语言的最佳实践，最重要的是——<strong>它对人类审查者极其友好</strong>。</p>
</li>
</ul>
<p>在 AI 时代，我们开发者的工作重心正在从“写代码”，更多地转向“审查和指导 AI 写代码”。一门简单的、拥有短小精悍规范的语言，为我们和 AI 之间提供了一个共同的、易于理解的交流基础。</p>
<h2>小结：简洁，一种面向未来的选择</h2>
<p>回到最初的图表，它揭示了三种不同的设计哲学：</p>
<ul>
<li><strong>C++：</strong> “我给你一切，你自己想办法管好。”</li>
<li><strong>Rust：</strong> “我会替你管好一切，但你必须先理解我的全部规则。”</li>
<li><strong>Go：</strong> “我只给你几样最强大的工具，剩下的，我相信你的创造力。”</li>
</ul>
<p>Go 的简洁，不是功能的匮乏，而是一种深思熟虑的、面向未来的战略选择。它不仅<a href="https://tonybai.com/2024/10/24/cognitive-load-impact-on-programming-language-choice-and-study">降低了人类开发者的认知负荷</a>，更在不经意间，为即将到来的人机协作编程时代，铺平了道路。</p>
<p>因为当你的“同事”是一个 AI 时，一门简单、可预测、易于审查的语言，将是你最有价值的资产。</p>
<hr />
<p>你的Go技能，是否也卡在了“熟练”到“精通”的瓶颈期？</p>
<ul>
<li>想写出更地道、更健壮的Go代码，却总在细节上踩坑？</li>
<li>渴望提升软件设计能力，驾驭复杂Go项目却缺乏章法？</li>
<li>想打造生产级的Go服务，却在工程化实践中屡屡受挫？</li>
</ul>
<p>继《<a href="http://gk.link/a/10AVZ">Go语言第一课</a>》后，我的《<a href="http://gk.link/a/12yGY">Go语言进阶课</a>》终于在极客时间与大家见面了！</p>
<p>我的全新极客时间专栏 《<a href="http://gk.link/a/12yGY">Tony Bai·Go语言进阶课</a>》就是为这样的你量身打造！30+讲硬核内容，带你夯实语法认知，提升设计思维，锻造工程实践能力，更有实战项目串讲。</p>
<p>目标只有一个：助你完成从“Go熟练工”到“Go专家”的蜕变！ 现在就加入，让你的Go技能再上一个新台阶！</p>
<p><img src="https://tonybai.com/wp-content/uploads/course-card/iamtonybai-banner-2.gif" alt="" /></p>
<hr />
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求，请扫描下方公众号二维码，与我私信联系。</p>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p style='text-align:left'>&copy; 2025, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2025/07/25/go-vs-rust-vs-cpp-in-complexity/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rust 的安全神话？数据库 CEO 为何在关键系统中仍选 C++</title>
		<link>https://tonybai.com/2025/07/22/cedardb-choose-cpp-rather-than-rust/</link>
		<comments>https://tonybai.com/2025/07/22/cedardb-choose-cpp-rather-than-rust/#comments</comments>
		<pubDate>Tue, 22 Jul 2025 13:29:28 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[CPU]]></category>
		<category><![CDATA[GC]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[Rust]]></category>
		<category><![CDATA[unsafe]]></category>
		<category><![CDATA[借用检查器]]></category>
		<category><![CDATA[内存安全]]></category>
		<category><![CDATA[内存管理]]></category>
		<category><![CDATA[可变引用]]></category>
		<category><![CDATA[所有权系统]]></category>
		<category><![CDATA[标准库]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=4931</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/07/22/cedardb-choose-cpp-rather-than-rust 大家好，我是Tony Bai。 近年来，Rust 语言无疑是技术圈最炙手可热的明星。它以“内存安全”的核心承诺，向统治了系统编程领域数十年的 C++ 发起了强有力的挑战。无数文章和布道者都在宣扬一个近乎“神话”的观点：用 Rust，你就能告别段错误和内存泄漏。 然而，就在这股“Rust 替换一切”的热潮中，一个来自行业核心的声音，给我带来了深深的思考。 Moritz Sichert，高性能数据库 CedarDB 的联合创始人兼 CEO，最近发表了一个“反直觉”的观点： “Rust 是一门很棒的语言，我真的很喜欢用它。然而，当涉及到数据库系统时，我仍然会选择 C++ 而不是 Rust。” 一个数据库 CEO，在一个对数据安全和系统稳定性要求极致的领域，放弃了以“安全”著称的 Rust，转而拥抱充满了“历史遗留问题”的 C++。这究竟是为什么？ 这并非一次简单的“厚此薄彼”，而是一场关于工程现实与语言哲学之间深刻权衡的精彩案例。 理论安全 vs 工程现实：unsafe 的“逃生舱口” Moritz 首先承认了 Rust 的优点：理论上，Rust 通过其所有权系统和借用检查器，提供了远超 C++ 的默认安全性。这正是大家喜爱 Rust 的原因。 但问题在于，像 CedarDB 这样的高性能数据库，其开发工作远不止是处理业务逻辑。它需要深入到硬件的毛细血管中，榨干每一滴性能。这意味着： 使用大量底层的 CPU 特性。 实现复杂的侵入式数据结构。 进行带有验证的、乐观且激进的内存访问。 在这些场景下，Rust 的安全检查反而成了“束缚”。为了完成任务，你必须使用 Rust 提供的“逃生舱口”——unsafe 关键字。 而 Moritz [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2025/cedardb-choose-cpp-rather-than-rust-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/07/22/cedardb-choose-cpp-rather-than-rust">本文永久链接</a> &#8211; https://tonybai.com/2025/07/22/cedardb-choose-cpp-rather-than-rust</p>
<p>大家好，我是Tony Bai。</p>
<p>近年来，Rust 语言无疑是技术圈最炙手可热的明星。它以“内存安全”的核心承诺，向统治了系统编程领域数十年的 C++ 发起了强有力的挑战。无数文章和布道者都在宣扬一个近乎“神话”的观点：用 Rust，你就能告别段错误和内存泄漏。</p>
<p>然而，就在这股“Rust 替换一切”的热潮中，一个来自行业核心的声音，给我带来了深深的思考。</p>
<p><strong>Moritz Sichert</strong>，高性能数据库 <strong>CedarDB</strong> 的联合创始人兼 CEO，最近发表了一个“反直觉”的观点：</p>
<blockquote>
<p>“Rust 是一门很棒的语言，我真的很喜欢用它。然而，当涉及到数据库系统时，我仍然会选择 C++ 而不是 Rust。”</p>
</blockquote>
<p><img src="https://tonybai.com/wp-content/uploads/2025/cedardb-choose-cpp-rather-than-rust-2.jpeg" alt="" /></p>
<p>一个数据库 CEO，在一个对数据安全和系统稳定性要求极致的领域，放弃了以“安全”著称的 Rust，转而拥抱充满了“历史遗留问题”的 C++。这究竟是为什么？</p>
<p>这并非一次简单的“厚此薄彼”，而是一场关于工程现实与语言哲学之间深刻权衡的精彩案例。</p>
<h2>理论安全 vs 工程现实：unsafe 的“逃生舱口”</h2>
<p>Moritz 首先承认了 Rust 的优点：理论上，Rust 通过其所有权系统和借用检查器，提供了远超 C++ 的默认安全性。这正是大家喜爱 Rust 的原因。</p>
<p>但问题在于，像 CedarDB 这样的高性能数据库，其开发工作远不止是处理业务逻辑。它需要深入到硬件的毛细血管中，榨干每一滴性能。这意味着：</p>
<ul>
<li>使用大量底层的 CPU 特性。</li>
<li>实现复杂的侵入式数据结构。</li>
<li>进行带有验证的、乐观且激进的内存访问。</li>
</ul>
<p>在这些场景下，Rust 的安全检查反而成了“束缚”。为了完成任务，你必须使用 Rust 提供的“逃生舱口”——<strong>unsafe</strong> 关键字。</p>
<p>而 Moritz 抛出的重磅炸弹正在于此：</p>
<blockquote>
<p><strong>“一旦你在 Rust 中写下 unsafe 代码，所有的赌注都将失效。在 unsafe 代码中，你遇到未定义行为（UB, Undefined Bahavior）的风险，甚至比在 C++ 中还要高。”</strong></p>
</blockquote>
<h2>unsafe Rust：一个更危险的“黑暗森林”？</h2>
<p>这个论断足以颠覆许多人的认知。unsafe Rust 怎么会比 C++ 还危险？</p>
<p>关键在于理解 unsafe 到底意味着什么。它不是简单地“关闭”安全检查，而是程序员向编译器立下了一个<strong>契约</strong>：“<strong>编译器，请相信我，接下来的这段代码，我将手动保证它完全遵守 Rust 的内存模型和别名规则（Aliasing Rules）。</strong>”</p>
<p>这正是问题的核心所在。<br />
*   <strong>C++ 的危险是“已知的”</strong>：C++ 就像一片广阔的雷区，但经过几十年的探索，老兵们已经绘制出了详细的“排雷图”。虽然处处是坑，但如何避免、如何调试，已经积累了大量的工程实践和模式。<br />
*   <strong>unsafe Rust 的危险是“微妙的”</strong>：unsafe 区域就像一个“黑暗森林”，你不仅要面对 C++ 程序员熟悉的裸指针、内存布局等问题，更要命的是，你还必须手动维护 Rust 那套比 C++ 更为严格的别名规则（例如，在任何给定时间，你只能有一个可变引用 &amp;mut T，或者任意数量的不可变引用 &amp;T，但不能两者都有）。</p>
<p>对于一位经验丰富的 C++ 开发者而言，在 unsafe 块里很容易不自觉地写出 C++ 风格的指针操作，却无意中违反了 Rust 的核心不变量，从而触发 UB。这种“新规则”下的自由，反而成了一个更容易跌落的陷阱。</p>
<p>Moritz 的观点是：在一个必须大量使用 unsafe 的项目中，与其在一个受严格规则约束的环境里“戴着镣铐跳舞”，不如直接选择那个虽然危险、但规则更为人熟知且自由度更高的 C++。</p>
<h2>聊聊 Go：一种不同的安全哲学</h2>
<p>那么，聊了这么多 Rust 和 C++，我们作为 Gopher 能从中得到什么启发呢？这恰好能让我们更深刻地理解 Go 的设计取舍。</p>
<p>Go 语言同样有一个 unsafe 包。但与 Rust 的设计哲学截然不同。</p>
<p>Rust 的 unsafe 是语言的<strong>一等公民</strong>，是其系统编程能力的重要组成部分，是为了实现“零成本抽象”而设计的必要工具。</p>
<p>而 Go 的 unsafe，从其文档的第一句话起，就在极力地“劝退”你：</p>
<blockquote>
<p>“任何使用了 unsafe 包的程序都可能在未来 Go 语言版本中无法移植……使用 unsafe 的代码，其安全性需要程序员手动保证，我们不建议使用。”</p>
</blockquote>
<p>在 Go 的世界里，unsafe 更像一个被严格限制的“后门”，而非一个功能特性。它的存在主要是为了实现标准库（如 runtime、sync），或在极少数与 C 库交互、进行极致性能微调的场景下使用。</p>
<p>我们可以这样总结三者的哲学：<br />
*   <strong>C++</strong>：默认给予你全部的权力与危险，安全是你的责任。<br />
*   <strong>Rust</strong>：默认提供极致的安全，但给你一个 unsafe 的选项，让你在立下严格契约为前提下重获权力。<br />
*   <strong>Go</strong>：默认通过 GC 和简单的内存模型提供高度的工程安全与效率，unsafe 是一个官方不鼓励、非标准的“应急方案”。</p>
<p>Go 的选择是，在绝大多数场景下，宁愿牺牲掉那部分通过复杂手动内存管理换来的极限性能，也要保证语言模型的简单性和大规模团队协作的工程效率与安全。</p>
<h2>小结：没有神话，只有权衡</h2>
<p>Moritz Sichert 的观点，并非是对 Rust 的全盘否定，更不是在鼓吹 C++ 的回归。</p>
<p>它有力地击碎了“Rust=绝对安全”的技术神话，揭示了一个冰冷的工程现实：<strong>在任何复杂的系统中，安全都是一个连续的光谱，而不是一个二元的开关。</strong></p>
<p>当你的业务场景把你推向性能金字塔的顶尖，逼迫你大量使用 unsafe 时，Rust 的安全优势就会被削弱，其复杂的底层规则甚至可能成为新的风险来源。</p>
<p>这个案例告诉我们，技术选型永远没有“银弹”，<strong>只有基于特定问题、特定团队、特定目标的深刻权衡</strong>。作为开发者，我们最重要的能力，就是理解自己手中工具的设计哲学、优势边界以及它为之付出的代价。</p>
<p>对于绝大多数的后端服务、云原生应用而言，Go 和 Rust 提供的现代安全模型无疑是巨大的进步。但请记住，当有人在讨论“是否选择 C++”时，他可能不是在开历史的倒车，而是在思考一个我们尚未触及的、更深层次的工程问题。</p>
<hr />
<p>你的Go技能，是否也卡在了“熟练”到“精通”的瓶颈期？</p>
<ul>
<li>想写出更地道、更健壮的Go代码，却总在细节上踩坑？</li>
<li>渴望提升软件设计能力，驾驭复杂Go项目却缺乏章法？</li>
<li>想打造生产级的Go服务，却在工程化实践中屡屡受挫？</li>
</ul>
<p>继《<a href="http://gk.link/a/10AVZ">Go语言第一课</a>》后，我的《<a href="http://gk.link/a/12yGY">Go语言进阶课</a>》终于在极客时间与大家见面了！</p>
<p>我的全新极客时间专栏 《<a href="http://gk.link/a/12yGY">Tony Bai·Go语言进阶课</a>》就是为这样的你量身打造！30+讲硬核内容，带你夯实语法认知，提升设计思维，锻造工程实践能力，更有实战项目串讲。</p>
<p>目标只有一个：助你完成从“Go熟练工”到“Go专家”的蜕变！ 现在就加入，让你的Go技能再上一个新台阶！</p>
<p><img src="https://tonybai.com/wp-content/uploads/course-card/iamtonybai-banner-2.gif" alt="" /></p>
<hr />
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求，请扫描下方公众号二维码，与我私信联系。</p>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p style='text-align:left'>&copy; 2025, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2025/07/22/cedardb-choose-cpp-rather-than-rust/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>一张图读懂Go的生存之道：当“面条代码”来敲门</title>
		<link>https://tonybai.com/2025/07/16/when-spaghetti-code-knocks/</link>
		<comments>https://tonybai.com/2025/07/16/when-spaghetti-code-knocks/#comments</comments>
		<pubDate>Wed, 16 Jul 2025 13:08:01 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[Bug]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Channel]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[goroutine]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[meme]]></category>
		<category><![CDATA[Rust]]></category>
		<category><![CDATA[simplicity]]></category>
		<category><![CDATA[SpaghettiCode]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[共享内存]]></category>
		<category><![CDATA[内存安全]]></category>
		<category><![CDATA[内聚]]></category>
		<category><![CDATA[并发]]></category>
		<category><![CDATA[抽象]]></category>
		<category><![CDATA[接口]]></category>
		<category><![CDATA[控制流]]></category>
		<category><![CDATA[模式]]></category>
		<category><![CDATA[简单]]></category>
		<category><![CDATA[继承]]></category>
		<category><![CDATA[耦合]]></category>
		<category><![CDATA[面条代码]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=4912</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/07/16/when-spaghetti-code-knocks 大家好，我是Tony Bai。 最近，在网上看到一张关于编程语言的 Meme 图，它以一种黑色幽默的方式，精准地描绘了我们软件开发中一个永恒的敌人，以及 Go 语言那与众不同的应对之道。 在这张图中，一个名为“面条代码 (Spaghetti Code)”的恐怖死神，手持镰刀，一路“收割”。C++ 的门敞开着，流出鲜血；Java 的门也未能幸免；甚至以安全著称的 Rust，门上同样血迹斑斑。当死神狞笑着敲开 Go 的大门时，它迎来的不是束手就擒的羔羊，而是一个手持“简洁 (Simplicity)”大棒、严阵以待的 Gopher。 这张图不仅仅是个有趣的段子，它几乎完美地诠释了 Go 语言的设计哲学和生存之道。今天，我们就来深入解构这张图：这个名为“面条代码”的死神究竟是什么？为什么连 C++、Java 和 Rust 都难以抵挡？以及，Go 手中的“简洁之棒”，到底有多大威力？ 门后的敌人：什么是“面条代码”？ “面条代码”是一个非常形象的术语，用来描述那些结构混乱、难以理解和维护的代码。就像一碗意大利面，所有的面条都缠绕在一起，你很难理清任何一根面条的来龙去脉。 其技术特征通常包括： * 高耦合、低内聚： 模块之间盘根错节，互相依赖，而模块内部的功能却分散混乱。 * 复杂的控制流： 代码的执行路径像迷宫一样，充满了深层嵌套、隐式跳转和复杂的条件判断。 * 滥用继承和全局状态： 过深的继承层次和随处可见的全局变量，使得任何一个微小的改动都可能引发雪崩式的连锁反应。 “面条代码”是所有项目的噩梦，它会让 bug 修复变得像拆弹，让功能迭代举步维艰。 走廊里的倒下者：为什么它们如此脆弱？ Meme 中，死神轻松地“收割”了 C++、Java 甚至 Rust。这并非是说这些语言不好，恰恰相反，是因为它们太强大、太灵活了，以至于为“面条代码”的滋生提供了肥沃的土壤。 1. C++ &#38; Java：强大的抽象带来的“继承面条”与“模式面条” 它们强大的面向对象特性，如复杂的继承层次、多态、以及各种“企业级”设计模式，在带来灵活性的同时也打开了潘多拉的魔盒。 一个典型的 [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2025/when-spaghetti-code-knocks-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/07/16/when-spaghetti-code-knocks">本文永久链接</a> &#8211; https://tonybai.com/2025/07/16/when-spaghetti-code-knocks</p>
<p>大家好，我是Tony Bai。</p>
<p>最近，在网上看到一张关于编程语言的 Meme 图，它以一种黑色幽默的方式，精准地描绘了我们软件开发中一个永恒的敌人，以及 Go 语言那与众不同的应对之道。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/when-spaghetti-code-knocks-2.png" alt="" /></p>
<p>在这张图中，一个名为“面条代码 (Spaghetti Code)”的恐怖死神，手持镰刀，一路“收割”。C++ 的门敞开着，流出鲜血；Java 的门也未能幸免；甚至以安全著称的 Rust，门上同样血迹斑斑。当死神狞笑着敲开 Go 的大门时，它迎来的不是束手就擒的羔羊，而是一个手持“简洁 (Simplicity)”大棒、严阵以待的 Gopher。</p>
<p>这张图不仅仅是个有趣的段子，它几乎完美地诠释了 Go 语言的设计哲学和生存之道。今天，我们就来深入解构这张图：这个名为“面条代码”的死神究竟是什么？为什么连 C++、Java 和 Rust 都难以抵挡？以及，Go 手中的“简洁之棒”，到底有多大威力？</p>
<h2>门后的敌人：什么是“面条代码”？</h2>
<p>“面条代码”是一个非常形象的术语，用来描述那些结构混乱、难以理解和维护的代码。就像一碗意大利面，所有的面条都缠绕在一起，你很难理清任何一根面条的来龙去脉。</p>
<p>其技术特征通常包括：<br />
*   <strong>高耦合、低内聚：</strong> 模块之间盘根错节，互相依赖，而模块内部的功能却分散混乱。<br />
*   <strong>复杂的控制流：</strong> 代码的执行路径像迷宫一样，充满了深层嵌套、隐式跳转和复杂的条件判断。<br />
*   <strong>滥用继承和全局状态：</strong> 过深的继承层次和随处可见的全局变量，使得任何一个微小的改动都可能引发雪崩式的连锁反应。</p>
<p>“面条代码”是所有项目的噩梦，它会让 bug 修复变得像拆弹，让功能迭代举步维艰。</p>
<h2>走廊里的倒下者：为什么它们如此脆弱？</h2>
<p>Meme 中，死神轻松地“收割”了 C++、Java 甚至 Rust。这并非是说这些语言不好，恰恰相反，是因为它们太强大、太灵活了，以至于为“面条代码”的滋生提供了肥沃的土壤。</p>
<p><strong>1. C++ &amp; Java：强大的抽象带来的“继承面条”与“模式面条”</strong></p>
<p>它们强大的面向对象特性，如复杂的继承层次、多态、以及各种“企业级”设计模式，在带来灵活性的同时也打开了潘多拉的魔盒。</p>
<p>一个典型的 Java “模式面条”可能长这样：</p>
<pre><code class="java">// 一个看似“设计良好”的支付服务
@Component
public class PaymentServiceImpl implements PaymentService {
    @Autowired
    private ValidatorFactory validatorFactory;

    @Autowired
    @Qualifier("creditCardProcessor")
    private PaymentProcessor creditCardProcessor;

    @Override
    public Response processPayment(Request request) {
        // ... 一系列复杂的调用和“魔法”注入
        Validator validator = validatorFactory.getValidator(request.getType());
        validator.validate(request);
        // ...
        return creditCardProcessor.process(request);
    }
}
</code></pre>
<p>这段代码的背后，是 Spring 框架通过注解实现的庞大依赖注入网络。程序的控制流不再是清晰的线性调用，而是被框架的“魔法”所接管，一旦出现问题，调试起来极其困难。</p>
<p><strong>2. Rust：“为编译器而战”催生的“生命周期面条”</strong></p>
<p>将 Rust 列为受害者，可能会引起争议。Rust 的所有权和借用检查器，确实能从根本上杜绝内存安全问题。但正是这种严格的约束，在某些复杂场景下，可能会迫使开发者写出为了“通过编译”而扭曲的、难以理解的代码。</p>
<p>比如，当处理复杂的数据结构和引用时，你可能会看到这样的“生命周期面条”：</p>
<pre><code class="rust">// 一个为了满足借用检查器而变得复杂的函数签名
fn process_data&lt;'a, 'b, 'c&gt;(
    config: &amp;'a Config,
    data: &amp;'b mut Data&lt;'c&gt;,
) -&gt; Result&lt;&amp;'b str, Error&gt;
where
    'a: 'b,
    'c: 'b
{
    // ... 一系列为了摆平生命周期而进行的复杂操作
    // ... 这段代码逻辑上可能很简单，但类型签名却极其复杂
}
</code></pre>
<p>这种代码虽然内存安全，但其认知负荷极高，新成员很难快速理解和维护。</p>
<h2>Gopher 的武器：挥舞“简洁之棒”的五种招式</h2>
<p>当“面条代码”的死神来到 Go 的门前，它发现这里没有复杂的继承、没有隐式的框架魔法、也没有纠结的生命周期。Gopher 手中的“简洁之棒”，是一套组合拳，招招打在“面条代码”的要害上。</p>
<p><strong>第一式：拥抱小接口</strong></p>
<p>Go 的接口是隐式实现的。这鼓励开发者定义小的、职责单一的接口。一个函数不应该依赖一个庞大的具体实现，而应该依赖它所需要的最小行为。</p>
<pre><code class="go">// "面条"代码：依赖具体的文件类型
func processFile(f *os.File) { /* ... */ }

// "简洁"代码：依赖 io.Reader 接口，更通用，更易测试
func processData(r io.Reader) { /* ... */ }
</code></pre>
<p><strong>第二式：拒绝深层嵌套</strong></p>
<p>Go 强制的 if err != nil 显式错误处理，杜绝了异常带来的隐式控制流。配合“前置守卫 (Guard Clauses)”的编码风格，可以让代码路径保持线性，避免“右斜”的箭头型代码。</p>
<pre><code class="go">// "面条"代码：深层嵌套
func process(p Params) error {
    if err := validate1(p); err == nil {
        if result, err := callService(p); err == nil {
            // ... 核心逻辑
        } else {
            return err
        }
    } else {
        return err
    }
    return nil
}

// "简洁"代码：使用 Guard Clauses
func process(p Params) error {
    if err := validate1(p); err != nil {
        return err
    }
    result, err := callService(p)
    if err != nil {
        return err
    }
    // ... 核心逻辑
    return nil
}
</code></pre>
<p><strong>第三式：构建清晰的并发管道</strong></p>
<p>面对并发，Go 不鼓励使用复杂的锁和共享内存，而是提倡“通过通信来共享内存”。使用 Channel 可以将复杂的并发任务，拆解成流水线式的、易于推理的独立阶段。</p>
<pre><code class="go">// 可能的"面条"代码：使用锁和共享状态，难以推理
var mu sync.Mutex
var data []int
// ... 多个 goroutine 通过 mu 来操作 data

// "简洁"代码：使用 Channel 构建数据管道
func generator(done &lt;-chan struct{}, nums ...int) &lt;-chan int { /*...*/ }
func square(done &lt;-chan struct{}, in &lt;-chan int) &lt;-chan int { /*...*/ }
// main 函数中将它们串联起来，清晰明了
</code></pre>
<p><strong>第四式：善用包的边界</strong></p>
<p>Go 通过首字母的大小写来控制成员的可见性。这是一种简单而强大的封装机制，它强制开发者思考包与包之间的边界，防止内部实现细节泄露，从而避免了模块间的强耦合。</p>
<p><strong>第五式：相信 gofmt</strong></p>
<p>Go 将代码格式化提升到了语言工具链的层面。gofmt 结束了所有关于代码风格的“圣战”，让所有 Go 代码看起来都像一个人写的。这极大地降低了团队协作中的沟通成本和代码阅读的认知负荷。</p>
<h2>更深层次的战斗：对抗软件的“熵增定律”</h2>
<p>Meme 图背后的战斗，其实远超语言层面。软件系统就像一个孤立的物理系统，天然地趋向于无序和混乱，这就是<strong>“软件的熵增定律”</strong>。</p>
<p>“面条代码”的死神，正是这一定律的化身。我们开发者，在日常工作中总在不自觉地为它敞开大门：<br />
*   <strong>功能的诱惑：</strong> 为了满足不断叠加的业务需求，我们倾向于“添加”代码，而不是“重构”。<br />
*   <strong>过早的抽象：</strong> 为了所谓的“未来扩展性”，引入了大量当前并不需要的复杂设计模式。<br />
*   <strong>简历驱动开发 (RDD)：</strong> 为了使用某个时髦的技术，而强行扭曲项目的设计。</p>
<p>Go 语言及其社区文化，本质上是在倡导一种<strong>“反熵增”的工程纪律</strong>。它通过其简洁的设计，迫使我们时刻对复杂性保持警惕。Go 的谚语“A little copying is better than a little dependency”（一点点复制优于一点点依赖），正是对“过早抽象”的直接反击。</p>
<h2>小结：简洁，一种主动的防御</h2>
<p>Meme 中的 Gopher 并非天生神力，它只是选择了一种更聪明的战斗方式。它没有选择用更复杂、更华丽的武器去和死神肉搏，而是用一把简单、坚固的“简洁之棒”，守住了自己的大门。</p>
<p>Go 的简洁，不是功能的匮乏，而是一种经过深思熟虑的设计选择，是一种主动防御复杂性的强大武器。它从语言层面就大大提高了制造“面条代码”的门槛。</p>
<p>对于我们所有工程师而言，无论使用何种语言，都应该从这张图中汲取智慧：<strong>成为那个手持大棒的 Gopher，时刻对不必要的复杂性说“不”。</strong> 这或许才是我们在软件开发这场持久战中，最终的生存之道。</p>
<hr />
<p>你的Go技能，是否也卡在了“熟练”到“精通”的瓶颈期？</p>
<ul>
<li>想写出更地道、更健壮的Go代码，却总在细节上踩坑？</li>
<li>渴望提升软件设计能力，驾驭复杂Go项目却缺乏章法？</li>
<li>想打造生产级的Go服务，却在工程化实践中屡屡受挫？</li>
</ul>
<p>继《<a href="http://gk.link/a/10AVZ">Go语言第一课</a>》后，我的《<a href="http://gk.link/a/12yGY">Go语言进阶课</a>》终于在极客时间与大家见面了！</p>
<p>我的全新极客时间专栏 《<a href="http://gk.link/a/12yGY">Tony Bai·Go语言进阶课</a>》就是为这样的你量身打造！30+讲硬核内容，带你夯实语法认知，提升设计思维，锻造工程实践能力，更有实战项目串讲。</p>
<p>目标只有一个：助你完成从“Go熟练工”到“Go专家”的蜕变！ 现在就加入，让你的Go技能再上一个新台阶！</p>
<p><img src="https://tonybai.com/wp-content/uploads/course-card/iamtonybai-banner-2.gif" alt="" /></p>
<hr />
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求，请扫描下方公众号二维码，与我私信联系。</p>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p style='text-align:left'>&copy; 2025, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2025/07/16/when-spaghetti-code-knocks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Go考古：创始人亲述Go语言的“创世纪”</title>
		<link>https://tonybai.com/2025/07/03/meet-the-go-team-2012/</link>
		<comments>https://tonybai.com/2025/07/03/meet-the-go-team-2012/#comments</comments>
		<pubDate>Thu, 03 Jul 2025 04:06:39 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Channel]]></category>
		<category><![CDATA[chubby]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[GoogleIO]]></category>
		<category><![CDATA[goroutine]]></category>
		<category><![CDATA[Interface]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[KenThompson]]></category>
		<category><![CDATA[netchan]]></category>
		<category><![CDATA[nil]]></category>
		<category><![CDATA[Package]]></category>
		<category><![CDATA[RobertGriesemer]]></category>
		<category><![CDATA[RobPike]]></category>
		<category><![CDATA[Slice]]></category>
		<category><![CDATA[依赖]]></category>
		<category><![CDATA[依赖管理]]></category>
		<category><![CDATA[切片]]></category>
		<category><![CDATA[包]]></category>
		<category><![CDATA[少即是多]]></category>
		<category><![CDATA[抢占式]]></category>
		<category><![CDATA[接口]]></category>
		<category><![CDATA[数组]]></category>
		<category><![CDATA[简单]]></category>
		<category><![CDATA[类型]]></category>
		<category><![CDATA[组合]]></category>
		<category><![CDATA[继承]]></category>
		<category><![CDATA[编译]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=4866</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/07/03/meet-the-go-team-2012 大家好，我是Tony Bai。 2012 年，Google I/O 大会的舞台上，一个刚刚发布 1.0 版本的编程语言团队，正襟危坐。他们面对着全球开发者的审视和提问，这其中，就有三位图灵奖得主级别的传奇人物：Ken Thompson、Rob Pike 和 Robert Griesemer。 那一年，Go 1.0 的发布，是一个历史性的里程碑。它意味着一个承诺“向后兼容、稳定可靠”的 Go 语言，正式诞生。 今天，就让我们扮演一次“Go 语言考古学家”，拂去时间的尘埃，回到那个被称为“创世纪”的时刻，重温 Go Team 核心成员们的亲口讲述，探寻这门语言最纯粹的初心和设计哲学。 我们为何创造 Go？—— “厌倦了等待 C++ 编译” 在访谈中，当被问及创造 Go 的初衷时，Rob Pike 给出了一个近乎“玩笑”却又无比真实的答案： “我们厌倦了等待 C++ 的编译。” 他生动地描绘了当时在 Google 内部的日常：为了构建一个巨大的 C++ 二进制文件，团队成员不得不在庞大的计算集群上等待超过一个小时。 更令人抓狂的是失控的依赖管理。Rob Pike 提到，他的同事 Mike Burrows（Chubby 的作者）在一次漫长的编译中发现，一个他从未听说过的、与项目毫无关系的头文件，竟然被重复编译了 37,000 次！ “当你用 ifdef 宏来保护依赖时，你最终得到的就是一个极其稠密的、做了太多无用功的依赖之巢。” [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2025/meet-the-go-team-2012-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/07/03/meet-the-go-team-2012">本文永久链接</a> &#8211; https://tonybai.com/2025/07/03/meet-the-go-team-2012</p>
<p>大家好，我是Tony Bai。</p>
<p>2012 年，Google I/O 大会的舞台上，一个刚刚发布 1.0 版本的编程语言团队，正襟危坐。他们面对着全球开发者的审视和提问，这其中，就有三位图灵奖得主级别的传奇人物：Ken Thompson、Rob Pike 和 Robert Griesemer。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/meet-the-go-team-2012-2.png" alt="" /></p>
<p>那一年，Go 1.0 的发布，是一个历史性的里程碑。它意味着一个承诺“向后兼容、稳定可靠”的 Go 语言，正式诞生。</p>
<p>今天，就让我们扮演一次“Go 语言考古学家”，拂去时间的尘埃，回到那个被称为“创世纪”的时刻，重温 Go Team 核心成员们的亲口讲述，探寻这门语言最纯粹的初心和设计哲学。</p>
<h2>我们为何创造 Go？—— “厌倦了等待 C++ 编译”</h2>
<p>在访谈中，当被问及创造 Go 的初衷时，Rob Pike 给出了一个近乎“玩笑”却又无比真实的答案：</p>
<blockquote>
<p><strong>“我们厌倦了等待 C++ 的编译。”</strong></p>
</blockquote>
<p>他生动地描绘了当时在 Google 内部的日常：为了构建一个巨大的 C++ 二进制文件，团队成员不得不在庞大的计算集群上等待超过一个小时。</p>
<p>更令人抓狂的是失控的依赖管理。Rob Pike 提到，他的同事 Mike Burrows（Chubby 的作者）在一次漫长的编译中发现，一个他从未听说过的、与项目毫无关系的头文件，竟然被重复编译了 <strong>37,000 次</strong>！</p>
<p>“当你用 ifdef 宏来保护依赖时，你最终得到的就是一个极其稠密的、做了太多无用功的依赖之巢。” Rob Pike 总结道。</p>
<p>这个巨大的痛点，催生了 Go 最核心的设计目标之一：<strong>从语言层面，彻底解决依赖问题。</strong></p>
<ul>
<li><strong>清晰的依赖图：</strong> Go 的导入路径直接明了。</li>
<li><strong>拒绝无用功：</strong> 编译器会拒绝未被使用的导入。</li>
<li><strong>高效的编译链：</strong> 设计上保证了“编译包 A 不应再重新编译包 C（如果 A->B->C）”。一旦包 B 被编译，它就携带了关于 C 的所有必要信息。</li>
</ul>
<p>而对于另一位创始人、C 语言和 Unix 的共同发明者 Ken Thompson 来说，促使他下定决心的“临门一脚”则更为直接和幽默。当被问及为何对 Go 如此热情时，他言简意赅：</p>
<blockquote>
<p><strong>“当我试图去读 C++0x（即 C++11）的标准草案时，我就下定决心了。”</strong></p>
</blockquote>
<p>全场爆笑。在一门日趋复杂的巨型语言面前，三位大师不约而同地选择了<strong>回归简单</strong>。</p>
<h2>Go 的“魔法”时刻 —— 那些改变编程方式的设计</h2>
<p>Go 的简洁并非简陋。在这次访谈中，创始人们也分享了那些让他们自己都感到惊喜和自豪的“魔法”设计。</p>
<p><strong>Slices (切片)：Ken Thompson 的神来之笔</strong></p>
<p>Rob Pike 回忆道，团队曾为了“数组”到底该如何工作而苦恼了整整一年。他们既想要静态检查的固定长度数组，又渴望某种形式的可变长度数组。在无数次的挣扎后，有一天，Ken Thompson 带着 slice 的想法走进办公室。</p>
<p>“起初我们并不确定这是不是正确答案，” Rob Pike 说，“但一旦我们开始使用它，一切都变得显而易见。” 一个简单而优雅的设计，完美地解决了这个旷日持久的难题。</p>
<p><strong>Interfaces (接口)：Rob Pike 的挚爱</strong></p>
<p>对于 Rob Pike 而言，接口是他认为 Go 中最强大的特性。</p>
<blockquote>
<p><strong>“接口深刻地改变了我对软件开发的思考方式。一个程序由这些可以轻松‘粘合’在一起的东西组成，这种感觉太棒了。它改变了软件被构建的方式。”</strong></p>
</blockquote>
<p>Go 的接口是隐式实现的。这种非侵入式的设计，让组件之间的耦合度降至最低，极大地促进了代码的解耦和可组合性。</p>
<p><strong>Packages (包)：看似显然，实则艰难</strong></p>
<p>今天我们觉得理所当然的 Go 包机制——一个包可以由多个文件组成，包内全局变量可以任意顺序声明——在当时也是经过了无数次辩论才最终成型的。</p>
<p>“它看起来似乎是显而易见的，但要弄清楚这一点真的非常困难。” Rob Pike 感叹道。这种“松散”的包设计，极大地简化了代码组织和重构的难度。</p>
<h2>有所为，有所不为 —— Go 的设计权衡</h2>
<p>当被问及如何看待 D 语言等其他试图改进 C++ 的语言时，Robert Griesemer 阐述了 Go 截然不同的设计哲学：</p>
<blockquote>
<p><strong>“我的印象是，D 语言会像 C++ 一样不断成长。而在 Go 中，我们试图采取完全相反的方式：尽可能地移除东西，将其简化到骨架，只保留你构建一切所需的绝对最小值。”</strong></p>
</blockquote>
<p>他相信，如果这些小组件是正交且能良好协作的，最终得到的东西会比拥有大量相互掣肘的特性的语言更强大。</p>
<p>这种“少即是多”的哲学，体现在 Go 对许多“流行特性”的刻意“缺失”上。当被问及“最庆幸 Go 缺失了什么特性”时，团队成员提到了：</p>
<ul>
<li><strong>类型继承体系 (Type Hierarchy)</strong></li>
<li><strong>可选参数 (Optional Arguments)</strong></li>
<li><strong>列表推导式 (List Comprehensions)</strong></li>
<li><strong>三元运算符</strong></li>
</ul>
<p>Rob Pike 指出，在 Java 或 C++ 中，你通常从设计类型继承树开始。这项工作耗时耗力，一旦发现设计有误，回头修改的成本极高。Go 通过移除类型继承，让程序在演进过程中更易于调整和适应。</p>
<p>为了凸显 Go 的简洁与 C++ 的复杂之间的对比，Rob Pike 更是转述了当时未能到场的 Russ Cox 的一句玩笑话，它为 Go 的哲学做了最好的注脚：<br />
“C++ 的风格指南里条条框框，而 Go 的风格指南第一句或许应该是：你可以使用这门语言的全部。”</p>
<h2>回望 2012 的“预言” —— 那些已实现和仍在路上的事</h2>
<p>考古的乐趣，在于用今天的视角去审视昨天的预言。在 2012 年，Go Team 对未来的展望，如今看来既有惊人的远见，也留下了些许历史的印记。</p>
<ul>
<li><strong>对 Go 1.1 的精准预言：</strong> 他们当时预测 1.1 版本将专注于性能提升、GC 改进、调度器优化和对更多操作系统的支持。这与后来 Go 1.x 系列的演进路径完全吻合。</li>
<li><strong>对 Go 2.0 的务实态度：</strong> 团队明确表示“Go 2 遥遥无期”，Go 2 的新想法将来自于使用 Go 1 中发现的真实需求。这个务实的态度至今仍在指导着 Go 的发展。</li>
<li><strong>最大的“失误”？</strong> 当被问及此，团队坦诚地提到了 nil 指针（Tony Hoare 的“十亿美元的错误”），以及循环变量的作用域问题。这些话题，至今仍在社区中被热烈讨论。</li>
<li><strong>未解的难题与渴望：</strong> Rob Pike 当时多次提到，他们非常想实现但还没找到完美方案的“网络化的 Channel (netchan)”，以及对一个真正的“抢占式调度器”的渴望。这些难题，在后来的岁月里，通过不同的方式被逐步探索和解决。</li>
</ul>
<h2>小结：回到源头，理解初心</h2>
<p>穿越时空，回到 Go 语言的“创世纪”现场，我们听到的不是高深莫测的理论，而是一群务实的工程师，为了解决自己在日常工作中遇到的真实、具体的痛点，而进行的一场充满智慧、权衡与热情的创造。</p>
<p>他们对简洁的极致追求，对工程效率的深刻理解，以及对“少即是多”的坚定信念，共同塑造了今天我们所热爱的 Go 语言。</p>
<p>理解这段历史，就是理解 Go 的灵魂。</p>
<p>参考资料链接：https://www.youtube.com/watch?v=sln-gJaURzk</p>
<hr />
<p>你的Go技能，是否也卡在了“熟练”到“精通”的瓶颈期？</p>
<ul>
<li>想写出更地道、更健壮的Go代码，却总在细节上踩坑？</li>
<li>渴望提升软件设计能力，驾驭复杂Go项目却缺乏章法？</li>
<li>想打造生产级的Go服务，却在工程化实践中屡屡受挫？</li>
</ul>
<p>继《<a href="http://gk.link/a/10AVZ">Go语言第一课</a>》后，我的《<a href="http://gk.link/a/12yGY">Go语言进阶课</a>》终于在极客时间与大家见面了！</p>
<p>我的全新极客时间专栏 《<a href="http://gk.link/a/12yGY">Tony Bai·Go语言进阶课</a>》就是为这样的你量身打造！30+讲硬核内容，带你夯实语法认知，提升设计思维，锻造工程实践能力，更有实战项目串讲。</p>
<p>目标只有一个：助你完成从“Go熟练工”到“Go专家”的蜕变！ 现在就加入，让你的Go技能再上一个新台阶！</p>
<p><img src="https://tonybai.com/wp-content/uploads/course-card/iamtonybai-banner-2.gif" alt="" /></p>
<hr />
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求，请扫描下方公众号二维码，与我私信联系。</p>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p style='text-align:left'>&copy; 2025, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2025/07/03/meet-the-go-team-2012/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>“骑手与大象”架构：超越微服务与单体之争的务实之道？</title>
		<link>https://tonybai.com/2025/06/17/rider-elephant-arch/</link>
		<comments>https://tonybai.com/2025/06/17/rider-elephant-arch/#comments</comments>
		<pubDate>Tue, 17 Jun 2025 00:13:39 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Channel]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[CPU]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[goroutine]]></category>
		<category><![CDATA[gRPC]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[microservice]]></category>
		<category><![CDATA[NextJS]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Rust]]></category>
		<category><![CDATA[内存管理]]></category>
		<category><![CDATA[分布式]]></category>
		<category><![CDATA[务实]]></category>
		<category><![CDATA[单体]]></category>
		<category><![CDATA[大象与骑手]]></category>
		<category><![CDATA[微服务]]></category>
		<category><![CDATA[构建]]></category>
		<category><![CDATA[架构]]></category>
		<category><![CDATA[架构模式]]></category>
		<category><![CDATA[标准库]]></category>
		<category><![CDATA[生产力]]></category>
		<category><![CDATA[编译]]></category>
		<category><![CDATA[表达力]]></category>
		<category><![CDATA[语法糖]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=4827</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/06/17/rider-elephant-arch 大家好，我是Tony Bai。 在软件架构的江湖里，关于“微服务”与“单体”的论战，几乎从未停歇。一方推崇微服务的灵活性、可扩展性和独立部署，另一方则坚守单体的简洁性、低通信开销和易于本地调试。近年来，我们甚至看到像亚马逊 Prime Video 这样重量级的玩家，也公开分享了其从微服务“回归”到某种形式的单体（或者说更粗粒度的服务）的实践，引发了业界新一轮的思考。 这不禁让我们反问：微服务与单体，真的就是非此即彼的“二元对立”吗？ 最近，国外一家名为DealGate公司的一篇文章《Introducing the Rider and Elephant Software Architecture》，提出了一种他们称之为“骑手与大象”的架构模式，试图在这场看似无解的争论中，找到一条务实的中间道路。这种模式不仅在他们的实践中取得了显著成效，其背后的设计哲学和对技术选型的思考，也颇具启发意义。 “骑手与大象”：一个古老隐喻的现代架构演绎 DealGate 将其架构模式命名为“骑手与大象”，其灵感来源于心理学中的一个经典比喻：人类的思维由两部分组成——理性的“骑手”（对应我们发达的前额叶皮层，负责规划、分析和决策）和感性的、更强大的“大象”（对应我们原始的、更底层的“蜥蜴脑”或“穴居人脑”，驱动着本能和情绪）。骑手虽然可以尝试引导大象，但无法完全控制它；而如果骑手想独自前行，又会发现大象的力量是其无法比拟的。只有当骑手与大象协同合作时，才能发挥出最大的效能。 在 DealGate 的架构中，这个隐喻被巧妙地映射到了技术组件上： “大象 (Elephant)”：由 Go语言构建的应用。它不包含任何复杂的业务逻辑，但却承担着所有“脏活累活”——大规模的、高并发的数据处理。在 DealGate 的场景中，这可能意味着在任何时刻都有数万个 goroutine 在处理图像、PDF，抓取数千万级别的网页，并在每个网页上运行数千万次的正则表达式匹配。“大象”的核心职责是：强大、高效、能扛事儿。 “骑手 (Rider)”：由NextJS (Node.js) 构建的应用。它承载了所有的业务逻辑、数据库访问、用户交互等。“骑手”的核心职责是：灵活、敏捷、快速响应业务变化。 缰绳 (Communication)：“骑手”通过 gRPC 来“引导”和控制“大象”，两者之间保持低开销、高效率的通信。 这种架构的核心思想是：将需要极致性能和高并发处理的“重计算”部分（大象），与需要快速迭代和灵活业务逻辑的“轻应用”部分（骑手）进行分离，并让它们通过高效的通信方式协同工作。 为何选择“骑手与大象”？DealGate 的实践与思考 DealGate 之所以采用这种架构，源于他们在实际业务中遇到的挑战和对现有架构模式的反思。 对“微服务 vs 单体”的“虚假二分法”说不：他们认为，单纯地在微服务和单体之间做选择，往往忽略了业务的复杂性和多样性。他们希望能够“have the best of both worlds”（取两者之长）。 Node.js/NextJS 的局限性：尽管 DealGate 的主要应用是用 [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2025/rider-elephant-arch-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/06/17/rider-elephant-arch">本文永久链接</a> &#8211; https://tonybai.com/2025/06/17/rider-elephant-arch</p>
<p>大家好，我是Tony Bai。</p>
<p>在软件架构的江湖里，关于“微服务”与“单体”的论战，几乎从未停歇。一方推崇微服务的灵活性、可扩展性和独立部署，另一方则坚守单体的简洁性、低通信开销和易于本地调试。近年来，我们甚至看到像亚马逊 Prime Video 这样重量级的玩家，也公开分享了其从微服务“回归”到某种形式的单体（或者说更粗粒度的服务）的实践，引发了业界新一轮的思考。</p>
<p>这不禁让我们反问：<strong>微服务与单体，真的就是非此即彼的“二元对立”吗？</strong></p>
<p>最近，国外一家名为DealGate公司的一篇文章《Introducing the Rider and Elephant Software Architecture》，提出了一种他们称之为“骑手与大象”的架构模式，试图在这场看似无解的争论中，找到一条务实的中间道路。这种模式不仅在他们的实践中取得了显著成效，其背后的设计哲学和对技术选型的思考，也颇具启发意义。</p>
<h2>“骑手与大象”：一个古老隐喻的现代架构演绎</h2>
<p>DealGate 将其架构模式命名为“骑手与大象”，其灵感来源于心理学中的一个经典比喻：人类的思维由两部分组成——理性的“骑手”（对应我们发达的前额叶皮层，负责规划、分析和决策）和感性的、更强大的“大象”（对应我们原始的、更底层的“蜥蜴脑”或“穴居人脑”，驱动着本能和情绪）。骑手虽然可以尝试引导大象，但无法完全控制它；而如果骑手想独自前行，又会发现大象的力量是其无法比拟的。只有当骑手与大象协同合作时，才能发挥出最大的效能。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/rider-elephant-arch-2.jpg" alt="" /></p>
<p>在 DealGate 的架构中，这个隐喻被巧妙地映射到了技术组件上：</p>
<ul>
<li>“大象 (Elephant)”：由 Go语言构建的应用。它不包含任何复杂的业务逻辑，但却承担着所有“脏活累活”——大规模的、高并发的数据处理。在 DealGate 的场景中，这可能意味着在任何时刻都有数万个 goroutine 在处理图像、PDF，抓取数千万级别的网页，并在每个网页上运行数千万次的正则表达式匹配。“大象”的核心职责是：强大、高效、能扛事儿。</li>
<li>“骑手 (Rider)”：由NextJS (Node.js) 构建的应用。它承载了所有的业务逻辑、数据库访问、用户交互等。“骑手”的核心职责是：灵活、敏捷、快速响应业务变化。</li>
<li>缰绳 (Communication)：“骑手”通过 <strong>gRPC</strong> 来“引导”和控制“大象”，两者之间保持低开销、高效率的通信。</li>
</ul>
<p>这种架构的核心思想是：将需要极致性能和高并发处理的“重计算”部分（大象），与需要快速迭代和灵活业务逻辑的“轻应用”部分（骑手）进行分离，并让它们通过高效的通信方式协同工作。</p>
<h2>为何选择“骑手与大象”？DealGate 的实践与思考</h2>
<p>DealGate 之所以采用这种架构，源于他们在实际业务中遇到的挑战和对现有架构模式的反思。</p>
<ul>
<li>对“微服务 vs 单体”的“虚假二分法”说不：他们认为，单纯地在微服务和单体之间做选择，往往忽略了业务的复杂性和多样性。他们希望能够“have the best of both worlds”（取两者之长）。</li>
<li>Node.js/NextJS 的局限性：尽管 DealGate 的主要应用是用 NextJS 编写的，但他们发现，即使 Node.js 在 I/O 和网络处理上有多线程优势，其正则表达式等 CPU 密集型操作仍然受限于单线程（JavaScript 的执行模型）。当需要在后台进行大量正则匹配，同时还要响应 Web 应用请求时，性能瓶颈就显而易见了。</li>
<li>Go 语言的“大象”潜质：文章中明确指出：“Go语言非常适合这种场景，你可以轻松地扔给它数万个CPU密集型进程，它会愉快地处理掉所有这些”。这充分肯定了 Go 语言在并发处理和性能方面的核心优势。</li>
<li>对微服务通信开销的警惕：DealGate 批评了许多微服务架构使用 JSON 进行进程间通信的做法，认为其“序列化和反序列化开销是令人发指的”。他们选择 gRPC，正是为了最大限度地降低“骑手”与“大象”之间的通信成本，确保即使在需要传输大量数据（因为“大象”不包含业务逻辑，需要被视为“愚笨的工人”）的情况下，也能保持高效。</li>
</ul>
<h2>Go 语言：扮演“大象”的理想之选</h2>
<p>在“骑手与大象”的架构中，Go 语言之所以被选中扮演“吃苦耐劳的大象”，并非偶然。这得益于 Go 语言的核心特性：</p>
<ol>
<li>极致的并发性能：Goroutine 和 Channel 机制，配合高效的调度器，使得 Go 能够轻松创建和管理海量的并发任务，这对于处理 DealGate 所述的“数万个 goroutine 同时处理数据”的场景至关重要。</li>
<li>高效的执行效率：Go 语言编译为原生机器码，其性能接近 C/C++，远超解释型语言，非常适合 CPU 密集型的数据处理任务。</li>
<li>强大的标准库：Go 的标准库提供了丰富的网络编程、文本处理（包括正则表达式）、数据编解码等功能，为构建“大象”应用提供了坚实的基础。</li>
<li>简洁的部署：Go 应用可以编译成单个静态链接的可执行文件，部署简单，依赖少。</li>
</ol>
<p>可以说，Go 语言的设计哲学和核心能力，使其成为承载这种“无业务逻辑、高并发、重计算”角色的理想选择。</p>
<h2>语言选型的“二八原则”与“务实主义”</h2>
<p>“骑手与大象”架构的另一个核心启示，在于其对不同技术栈的选择策略，体现了一种深刻的“务实主义”和对“成本效益”的考量。</p>
<p>文章明确反驳了“既然有更高性能的语言（如 Rust 或 Go 本身），为什么不把所有应用都用它来写？”的观点，并将其类比为“那所有应用都应该用汇编来写了”。</p>
<p>其核心逻辑是：</p>
<ul>
<li>高级语言（如 JavaScript, Python）的优势：更安全（内存管理等）、生产力更高（表达力强、语法糖和轮子多）、开发者社群更大、单位时间开发成本相对更低。</li>
<li>高性能/底层语言（如 Go, Rust, C++）的优势：性能极致、对系统资源有更精细的控制。但通常也意味着更陡峭的学习曲线、更高的开发成本、以及（在某些情况下）更长的开发周期。</li>
</ul>
<p>DealGate 的策略是：<strong>“在你必须快的地方快，其他一切都选择高级语言和（相对）单体的模式。”</strong> 这意味着：</p>
<ul>
<li>将昂贵的、需要精细优化的<strong>高性能代码（大象）限制在最小的必要范围内</strong>（例如，只占整个业务系统的 10%）。</li>
<li>将大部分的<strong>业务逻辑、用户交互（骑手）用生产力更高、开发更快的高级语言来实现</strong>。</li>
</ul>
<p>这种“混合编程”或“多语言架构”的思路，实际上是在性能、开发效率、人才获取成本、维护成本等多个维度之间进行权衡和优化。它提醒我们，技术选型不应盲目追求“最新最酷”或“性能极致”，而应服务于业务需求，并充分考虑团队和公司的实际情况。</p>
<p>文章中也提及了对“Just write Rust”（就用 Rust 写）这类口号的反思，指出大多数公司和开发者可能无法承担全员学习和使用像 Rust 这样“高门槛”语言的成本。这并非否定 Rust 的优秀，而是强调技术选型的现实约束。</p>
<h2>小结：“没有完美的解决方案，只有明智的权衡”</h2>
<p>“没有完美的解决方案，只有权衡取舍”。DealGate 的文章以这句经典的名言作为总结，恰如其分。</p>
<p>“骑手与大象”架构，正是在微服务的灵活性、分布式能力与单体的低心智负担、高开发效率之间做出的一种明智权衡。它并非适用于所有场景的“银弹”，但在类似 DealGate 这样需要处理大规模数据密集型任务，同时又需要快速迭代业务逻辑的场景下，无疑提供了一种极具价值的、务实的架构思路。</p>
<p>它也再次印证了一个朴素的道理：优秀的架构设计，往往不是对某种“主义”的盲从，而是对业务需求的深刻理解和对不同技术优劣的精准把握，最终在各种约束条件下找到那个“恰到好处”的平衡点。</p>
<p>或许，在微服务与单体的喧嚣争论之外，我们更应该学习这种“骑手与大象”的智慧——<strong>在正确的地方，用正确的方式，做正确的事情。</strong></p>
<p><strong>参考文献：</strong><br />
Introducing the Rider and Elephant Software Architecture &#8211; https://d-gate.io/blog/rider-and-elephant-architecture</p>
<hr />
<p><strong>聊一聊，也帮个忙：</strong></p>
<ul>
<li><strong>你如何看待 DealGate 提出的“骑手与大象”架构模式？它是否对你的项目有所启发？</strong></li>
<li><strong>在你的工作中，是否也遇到过类似的“微服务 vs 单体”或“高性能 vs 高生产力”的选型困境？你是如何权衡的？</strong></li>
<li><strong>Go 语言在你心目中，更适合扮演“骑手”还是“大象”的角色？或者两者皆可，取决于具体场景？</strong></li>
</ul>
<p>欢迎在<strong>评论区</strong>留下你的思考和经验。如果你觉得这篇文章提供了一个有价值的视角，也请<strong>转发给你身边的开发者和架构师朋友们</strong>，一起探讨更务实的架构之道！</p>
<hr />
<p><strong>精进有道，更上层楼</strong></p>
<p><a href="https://mp.weixin.qq.com/s/GWGWTfCRCsOJ_4Pk-pxpHA">极客时间《Go语言进阶课》上架刚好一个月</a>，受到了各位读者的热烈欢迎和反馈。在这里感谢大家的支持。目前我们已经完成了课程模块一『语法强化篇』的 13 讲，为你系统突破 Go 语言的语法认知瓶颈，打下坚实基础。</p>
<p>现在，我们即将进入模块二『设计先行篇』，这不仅包括 API 设计，更涵盖了项目布局、包设计、并发设计、接口设计、错误处理设计等构建高质量 Go 代码的关键要素。</p>
<p>这门进阶课程，是我多年 Go 实战经验和深度思考的结晶，旨在帮助你突破瓶颈，从“会用 Go”迈向“精通 Go”，真正驾驭 Go 语言，编写出更优雅、<br />
更高效、更可靠的生产级代码！</p>
<p>扫描下方二维码，立即开启你的 Go 语言进阶之旅！</p>
<p><img src="https://tonybai.com/wp-content/uploads/course-card/iamtonybai-banner-2.gif" alt="" /></p>
<hr />
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求，请扫描下方公众号二维码，与我私信联系。</p>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p style='text-align:left'>&copy; 2025, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2025/06/17/rider-elephant-arch/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Go还是Rust？2025年技术选型之辩</title>
		<link>https://tonybai.com/2025/06/15/rust-vs-go-2025/</link>
		<comments>https://tonybai.com/2025/06/15/rust-vs-go-2025/#comments</comments>
		<pubDate>Sat, 14 Jun 2025 23:57:52 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[cargo]]></category>
		<category><![CDATA[Channel]]></category>
		<category><![CDATA[cli]]></category>
		<category><![CDATA[Compiler]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[etcd]]></category>
		<category><![CDATA[GC]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[go1.24]]></category>
		<category><![CDATA[go1.25]]></category>
		<category><![CDATA[gohugo]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[goroutine]]></category>
		<category><![CDATA[Iot]]></category>
		<category><![CDATA[JetBrains]]></category>
		<category><![CDATA[k8s]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[map]]></category>
		<category><![CDATA[OS]]></category>
		<category><![CDATA[prometheus]]></category>
		<category><![CDATA[Result]]></category>
		<category><![CDATA[Rust]]></category>
		<category><![CDATA[RustRover]]></category>
		<category><![CDATA[swisstable]]></category>
		<category><![CDATA[terraform]]></category>
		<category><![CDATA[viper]]></category>
		<category><![CDATA[wasm]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[WebAssembly]]></category>
		<category><![CDATA[交叉编译]]></category>
		<category><![CDATA[借用]]></category>
		<category><![CDATA[区块链]]></category>
		<category><![CDATA[所有权]]></category>
		<category><![CDATA[生产力]]></category>
		<category><![CDATA[编译器]]></category>
		<category><![CDATA[设计哲学]]></category>
		<category><![CDATA[错误处理]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=4821</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/06/15/rust-vs-go-2025 大家好，我是Tony Bai。 技术圈的话题里，从来不缺少编程语言之争，并且这类话题向来热度不减。最近，JetBrains 旗下的 RustRover 博客发表了一篇题为《Rust vs Go: Which one to choose in 2025》的文章，并引用了《State of Developer Ecosystem Report 2024》的一些数据，再次将 Go 和 Rust 这两位“当红炸子鸡”推上了对比的擂台。 文章指出，Rust 和 Go 都在现代计算领域开辟了重要的生态位，尤其在系统级操作和并发处理方面备受赞誉。报告数据也颇为亮眼：Rust 的用户基数已达到约 227 万，其中 70.9 万开发者将其作为主要语言；而 Go 的用户基础依然稳固。但一个颇具“引战”潜力的数据点是——“约 1/6 的 Go 用户正在考虑转向 Rust”。 这不禁让人深思：这是否预示着某种趋势？在即将到来的 2025 年，当面临新的项目或技术升级时，我们究竟应该选择 Go 还是 Rust？作为一名在 Go 领域深耕多年的老兵，我想结合 RustRover 的这篇文章，谈谈我的一些看法，希望能为正在做技术选型的你，提供一些来自 Go 视角的参考。 文章核心观点速览(与Go的对比) [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2025/rust-vs-go-2025-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/06/15/rust-vs-go-2025">本文永久链接</a> &#8211; https://tonybai.com/2025/06/15/rust-vs-go-2025</p>
<p>大家好，我是Tony Bai。</p>
<p>技术圈的话题里，从来不缺少编程语言之争，并且这类话题向来热度不减。最近，JetBrains 旗下的 RustRover 博客发表了一篇题为《<a href="https://blog.jetbrains.com/rust/2025/06/12/rust-vs-go/">Rust vs Go: Which one to choose in 2025</a>》的文章，并引用了《<a href="https://tonybai.com/2025/04/10/jetbrains-2024-go-report-analysis/">State of Developer Ecosystem Report 2024</a>》的一些数据，再次将 Go 和 Rust 这两位“当红炸子鸡”推上了对比的擂台。</p>
<p>文章指出，Rust 和 Go 都在现代计算领域开辟了重要的生态位，尤其在系统级操作和并发处理方面备受赞誉。报告数据也颇为亮眼：Rust 的用户基数已达到约 227 万，其中 70.9 万开发者将其作为主要语言；而 Go 的用户基础依然稳固。但一个颇具“引战”潜力的数据点是——<strong>“约 1/6 的 Go 用户正在考虑转向 Rust”</strong>。</p>
<p>这不禁让人深思：这是否预示着某种趋势？在即将到来的 2025 年，当面临新的项目或技术升级时，我们究竟应该选择 Go 还是 Rust？作为一名在 Go 领域深耕多年的老兵，我想结合 RustRover 的这篇文章，谈谈我的一些看法，希望能为正在做技术选型的你，提供一些来自 Go 视角的参考。</p>
<h2>文章核心观点速览(与Go的对比)</h2>
<p>首先，我们简要回顾一下RustRover这篇博客文章中对两种语言核心特性和适用场景的概括（以下观点主要转述自原文）：</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/rust-vs-go-2025-2.png" alt="" /></p>
<h3>Rust的画像：极致安全与性能的追求者</h3>
<ul>
<li>核心理念：无 GC 的内存安全（所有权、借用机制，编译时强制检查），无数据竞争的并发。</li>
<li>性能表现：非常接近 C++，零成本抽象，计算密集型任务通常更快，内存占用更低。</li>
<li>适用场景：系统编程 (OS、嵌入式)、IoT、WebAssembly、区块链、云基础设施、网络编程、CLI 工具等对性能和安全要求极致的领域。</li>
<li>学习曲线：陡峭。所有权、借用、生命周期、以及严格的编译器对新手构成较大挑战。</li>
<li>生态：年轻但发展迅速，Cargo 包管理器和 crates.io 体验优秀，社区充满热情。但在库的全面性上可能尚不及 Go。</li>
</ul>
<p>Rust在内存安全和底层控制方面的确做到了极致，其编译期检查能消除许多运行时风险，这在特定高安全、高性能场景下是巨大优势。然而，这种极致是以显著牺牲开发效率和上手速度为代价的。</p>
<h3>Go的画像：简洁高效与工程化生产力的典范</h3>
<ul>
<li>核心理念：简洁、高效、可读性强，易学易用。</li>
<li>并发模型：内置 Goroutines 和 Channels，轻松实现高并发。</li>
<li>性能表现：高效的 GC，优秀的网络性能，尤其适合构建高并发网络服务。</li>
<li>适用场景：云基础设施 (Docker, K8s)、Web 服务与 API、网络编程、DevOps 工具、CLI 工具。</li>
<li>学习曲线：平缓。简约的设计哲学和少量关键字，使得 Go 非常容易上手。</li>
<li>生态：拥有强大且全面的标准库，成熟的工具链，以及庞大且活跃的社区，尤其在云原生领域具有主导地位。</li>
</ul>
<p>Go的核心竞争力在于其卓越的工程效率和在构建大规模分布式系统方面的成熟度。它的 GC 和并发模型虽然不如 Rust 那样在理论上“完美”，但在绝大多数实际应用中，提供了远超许多语言的生产力和性能平衡。</p>
<p>文章还从性能、易用性、并发、生态等多个维度对两者进行了对比，总体而言，强调了 Rust 在底层控制、内存安全和理论性能上的优势，以及 Go 在开发效率、并发易用性和生态成熟度上的长处。</p>
<h2>解读“1/6 Go 用户考虑转向 Rust”：是焦虑还是理性探索？</h2>
<p>这个数据点无疑是最引人注目的。我们该如何看待？</p>
<p>首先，<strong>不必过度焦虑</strong>。Go 语言的用户基数依然庞大且在持续增长。技术领域永远不乏对新工具、新范式的好奇与探索。一部分 Gopher 考虑 Rust，可能源于以下几点原因：</p>
<ul>
<li>对特定场景的极致追求：在某些对内存安全、性能要求达到严苛级别，且愿意投入更高学习成本的项目中（例如操作系统内核、游戏引擎、某些嵌入式系统），Rust 的特性确实更具吸引力。</li>
<li>技术视野的拓展：优秀的开发者总是乐于学习新事物。了解 Rust 的所有权模型等独特设计，本身就能拓宽技术视野，甚至反过来促进对 Go 并发安全和资源管理的更深理解。</li>
<li>对 Go 某些方面的“不满”：尽管 Go 的 GC 经过了多年优化，但在极少数对延迟极度敏感或内存分配模式特殊的场景下，GC 带来的不可预测性仍可能成为痛点。此外，Go 的错误处理方式（if err != nil）虽然清晰，但其冗余性也常被诟病。Rust 的 Result 类型和 ? 操作符提供了一种不同的体验。</li>
</ul>
<p>然而，<strong>“考虑转向”不等于“实际转向”，更不等于“大规模流失”</strong>。从“考虑”到在生产项目中大规模采用一种学习曲线陡峭、生态相对年轻的语言，中间还有很长的路要走。团队技能储备、项目时间压力、招聘难度、现有基础设施兼容性等都是现实的考量因素。</p>
<p>更重要的是，<strong>Go 语言自身也在不断进化</strong>。泛型的引入弥补了表达力上的一块短板；性能分析和调试工具日益完善；标准库持续增强；社区也在不断探索新的最佳实践。<a href="https://tonybai.com/2025/05/25/go-at-googleio-2025">Go团队对生产力和生产就绪的承诺</a>，使其能够持续满足绝大多数后端和云原生场景的需求。</p>
<h2>我的Go视角：场景驱动，务实选择，拥抱互补</h2>
<p>在我看来(可能也是很多Gopher的想法)，Go与Rust之争，很多时候并非“有你无我”的零和博弈，而更应回归到<strong>场景驱动的技术选型</strong>。</p>
<h3>Go的核心阵地依然稳固</h3>
<ul>
<li>高并发网络服务：Go 的 Goroutine + Channel 模型在构建需要处理大量并发连接的后端服务（如 API网关、微服务、消息队列等）时，其简洁性、高效性和成熟度依然是无与伦比的。这是 Go 的“龙兴之地”，也是其最强大的生态位。</li>
<li>云原生基础设施：Docker、Kubernetes、Prometheus、Terraform、Etcd……这些构建了现代云计算基石的项目，无一不是用 Go 编写。Go 在这个领域的生态、工具链和人才储备，使其成为构建云原生应用和平台的首选。</li>
<li>DevOps 与 CLI 工具：Go 编译速度快、交叉编译方便、部署简单（静态链接），使其成为编写各类运维工具、CLI 应用的理想选择。</li>
<li>追求工程效率和快速迭代的团队：Go 的简洁易学、快速编译和强大的标准库，使得团队能够快速上手、高效协作，快速将产品推向市场。</li>
</ul>
<h3>Rust 的独特优势区间</h3>
<ul>
<li>对内存安全和零开销抽象有极致要求的系统级编程：当你需要直接操作硬件、编写操作系统组件、或者开发对性能和资源控制要求极度严苛（且无法容忍 GC 暂停）的底层库时，Rust 的优势非常明显。</li>
<li>WebAssembly (Wasm)：Rust 凭借其性能和对 Wasm 的良好支持，在构建高性能 Web 前端组件或浏览器插件方面展现出巨大潜力。</li>
<li>安全关键领域：在一些对安全漏洞容忍度极低的领域，Rust 编译期的严格检查能提供更强的保障。</li>
</ul>
<h3>Go 与 Rust 的互补与融合</h3>
<p>早在2021年，时任谷歌Go编程语言的产品和战略负责人的<a href="https://github.com/spf13">史蒂夫·弗朗西亚（Steve Francia）</a>，也就是gohugo、viper等一簇明星Go开源项目的作者就曾提出过“<a href="https://tonybai.com/2021/03/15/rust-vs-go-why-they-are-better-together">Go与Rust强强联合</a>”的观点。</p>
<p>与其将Go与Rust视为绝对的竞争对手，不如看到它们的<strong>互补性</strong>。在一个复杂的系统中，完全可能出现 Go 与 Rust 各司其职的场景：例如，用 Rust 编写对性能和内存安全要求最高的底层核心计算模块或驱动，然后用 Go 来构建上层的业务逻辑、API 接口和分布式调度系统。这种“强强联合”或许是未来的一种趋势。</p>
<h2>给 Gopher 的建议：深耕当下，放眼未来</h2>
<p>面对 Rust 的崛起和社区的讨论，作为 Gopher，我们应该：</p>
<ol>
<li><strong>坚定对 Go 的信心：</strong> Go 在其核心优势领域（高并发、网络编程、云原生、工程效率）的地位依然稳固且在持续增强。Go 社区的活力和 Google 的持续投入，保证了 Go 的未来发展。</li>
<li><strong>深耕 Go 的核心能力：</strong> 充分理解和掌握 Go 的并发模型、内存管理、标准库和工具链，才能在实际项目中发挥其最大价值。不要因为外界的喧嚣而动摇对基础的夯实。</li>
<li><strong>保持开放心态，按需学习：</strong> 了解 Rust 等其他优秀语言的设计思想和适用场景，是有益的。如果你的工作场景确实需要 Rust 的特性，或者你对系统底层有浓厚兴趣，学习 Rust 会是一个很好的补充。但不必为了“时髦”而盲目追逐。</li>
<li><strong>关注 Go 的演进：</strong> Go 也在不断吸取社区反馈并进行改进。例如，对性能的持续优化（如 Go 1.24中map的Swiss Table实现、Go 1.25中新增的“绿茶”新GC）、对泛型的支持、对工具链的打磨等，都在让 Go 变得更好。</li>
<li><strong>技术选型，务实为本：</strong> 最终选择哪种语言，永远要服务于项目目标、团队能力和业务需求。没有“最好”的语言，只有“最合适”的语言。<a href="https://tonybai.com/2025/03/12/typescript-native-port-to-go">TypeScript编译器原生化选择Go</a>就是一个很好的例子。</li>
</ol>
<h2>小结：2025，Go 与 Rust 各自精彩</h2>
<p>RustRover 的文章及其引用的报告，为我们提供了一个观察当前编程语言生态动态的窗口。Rust 的确是一门优秀且充满潜力的语言，它在特定领域展现出的强大实力值得肯定。</p>
<p>然而，对于绝大多数追求高并发处理能力、高开发效率、快速迭代、以及需要在庞大而成熟的云原生生态中构建应用的场景而言，<strong>Go 语言在 2025 年乃至更远的未来，依然会是极其明智和强大的选择。</strong></p>
<p>“1/6 的 Go 用户考虑转向 Rust”，这或许正说明了 Go 社区的开发者们视野开阔，乐于学习。但更重要的是，在探索新可能的同时，我们更要清醒地认识到自己手中工具的价值和核心竞争力。</p>
<p>Go 与 Rust，未来更可能是并驾齐驱，在各自擅长的领域大放异彩，甚至在某些场景下携手共进。作为技术人，理解它们的区别与联系，做出最适合自己的选择，才是最重要的。</p>
<p>你对 Go 和 Rust 的未来怎么看？欢迎在评论区分享你的观点！</p>
<hr />
<p><strong>精进有道，更上层楼</strong></p>
<p><a href="https://mp.weixin.qq.com/s/GWGWTfCRCsOJ_4Pk-pxpHA">极客时间《Go语言进阶课》上架刚好一个月</a>，受到了各位读者的热烈欢迎和反馈。在这>里感谢大家的支持。目前我们已经完成了课程模块一『语法强化篇』的 13 讲，为你系统突破 Go 语言的语法认知瓶颈，打下坚实基础。</p>
<p>现在，我们即将进入模块二『设计先行篇』，这不仅包括 API 设计，更涵盖了项目布局、包设计、并发设计、接口设计、错误处理设计等构建高质>量 Go 代码的关键要素。</p>
<p>这门进阶课程，是我多年 Go 实战经验和深度思考的结晶，旨在帮助你突破瓶颈，从“会用 Go”迈向“精通 Go”，真正驾驭 Go 语言，编写出更优雅、<br />
更高效、更可靠的生产级代码！</p>
<p>扫描下方二维码，立即开启你的 Go 语言进阶之旅！</p>
<p><img src="https://tonybai.com/wp-content/uploads/course-card/iamtonybai-banner-2.gif" alt="" /></p>
<p><strong>感谢阅读！</strong></p>
<p>如果这篇文章让你对 Go 和 Rust有了新的认识，请帮忙转发，让更多朋友一起学习和进步！</p>
<hr />
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求，请扫描下方公众号二维码，与我私信联系。</p>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p style='text-align:left'>&copy; 2025, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2025/06/15/rust-vs-go-2025/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>11个现代Go特性：用gopls/modernize让你的代码焕然一新</title>
		<link>https://tonybai.com/2025/04/15/embrace-modern-go-style-with-gopls-modernize/</link>
		<comments>https://tonybai.com/2025/04/15/embrace-modern-go-style-with-gopls-modernize/#comments</comments>
		<pubDate>Mon, 14 Apr 2025 23:28:49 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[analyzer]]></category>
		<category><![CDATA[any]]></category>
		<category><![CDATA[Appendf]]></category>
		<category><![CDATA[BjarneStroustrup]]></category>
		<category><![CDATA[builtin]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[clone]]></category>
		<category><![CDATA[cmp]]></category>
		<category><![CDATA[Compare]]></category>
		<category><![CDATA[Concat]]></category>
		<category><![CDATA[Context]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[fmt]]></category>
		<category><![CDATA[for-range]]></category>
		<category><![CDATA[forloop]]></category>
		<category><![CDATA[generics]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[go-cache-prog]]></category>
		<category><![CDATA[go1.18]]></category>
		<category><![CDATA[go1.21]]></category>
		<category><![CDATA[goland]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[gopls]]></category>
		<category><![CDATA[Interface]]></category>
		<category><![CDATA[Iterator]]></category>
		<category><![CDATA[local-gitingest]]></category>
		<category><![CDATA[LSP]]></category>
		<category><![CDATA[maps]]></category>
		<category><![CDATA[max]]></category>
		<category><![CDATA[min]]></category>
		<category><![CDATA[ModernGo]]></category>
		<category><![CDATA[modernize]]></category>
		<category><![CDATA[omitzero]]></category>
		<category><![CDATA[range-over-int]]></category>
		<category><![CDATA[slices]]></category>
		<category><![CDATA[sort]]></category>
		<category><![CDATA[SplitSeq]]></category>
		<category><![CDATA[STL]]></category>
		<category><![CDATA[strings]]></category>
		<category><![CDATA[typeparameter]]></category>
		<category><![CDATA[vscode]]></category>
		<category><![CDATA[切片]]></category>
		<category><![CDATA[模板]]></category>
		<category><![CDATA[泛型]]></category>
		<category><![CDATA[类型参数]]></category>
		<category><![CDATA[语言服务器]]></category>
		<category><![CDATA[迭代器]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=4571</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/04/15/embrace-modern-go-style-with-gopls-modernize 大家好，我是Tony Bai。 最近在思考Go语言的发展时，不禁让我想起了当年学习C++的经历。Bjarne Stroustrup在《C++程序设计语言（特别版）》中就专门强调了“现代 C++”（Modern C++）的编程风格，鼓励使用模板、STL等新特性来编写更优雅、更高效的C++代码。 那么，我们热爱的Go语言，随着版本的不断迭代，是否也逐渐形成了一种“现代Go”（Modern Go）的风格呢？答案是肯定的。Go团队不仅在语言层面引入新特性（如泛型、range over int），也在标准库中添加了更强大、更便捷的包（如slices、maps）。 更棒的是，Go官方工具链gopls（Go Language Server Protocol的实现）中，就内置了一个名为modernize的分析器（Analyzer），专门用于帮助我们识别代码中可以用现代Go风格替代的“旧习”，并给出建议。 今天，我们就来深入了解一下gopls/modernize这个利器，看看它如何帮助我们的Go代码焕然一新，并学习一下它所倡导的11个“现代Go”风格语法要素具体包含哪些内容。 1. gopls/modernize分析器以及现代Go风格简介 gopls/modernize是golang.org/x/tools/gopls/internal/analysis/modernize 包提供的一个分析器。它的核心目标就是扫描你的Go代码，找出那些可以通过使用Go 1.18及之后版本引入的新特性或标准库函数来简化的代码片段。 modernize工具目前可以识别并建议修改多种“旧”代码模式。让我们逐一看看这些建议，并附上代码示例： (注：以下示例中的版本号指明了该现代写法是何时被推荐或可用的) 1). 使用min/max内建函数 (Go 1.21+) 旧风格： 使用 if/else 进行条件赋值来找最大/最小值。 func findMax(a, b int) int { var maxVal int if a &#62; b { maxVal = a } else { maxVal = [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/embrace-modern-go-style-with-gopls-modernize-1.jpg" alt="" /></p>
<p><a href="https://tonybai.com/2025/04/15/embrace-modern-go-style-with-gopls-modernize">本文永久链接</a> &#8211; https://tonybai.com/2025/04/15/embrace-modern-go-style-with-gopls-modernize</p>
<p>大家好，我是Tony Bai。</p>
<p>最近在思考Go语言的发展时，不禁让我想起了当年学习C++的经历。Bjarne Stroustrup在《<a href="https://book.douban.com/subject/1231576/">C++程序设计语言（特别版）</a>》中就专门强调了“现代 C++”（Modern C++）的编程风格，鼓励使用模板、STL等新特性来编写更优雅、更高效的C++代码。</p>
<p><img src="https://tonybai.com/wp-content/uploads/embrace-modern-go-style-with-gopls-modernize-2.jpg" alt="" /></p>
<p>那么，我们热爱的Go语言，随着版本的不断迭代，是否也逐渐形成了一种“现代Go”（Modern Go）的风格呢？答案是肯定的。Go团队不仅在语言层面引入新特性（如<a href="https://tonybai.com/2022/04/20/some-changes-in-go-1-18">泛型</a>、<a href="https://tonybai.com/2024/02/18/some-changes-in-go-1-22">range over int</a>），也在标准库中添加了更强大、更便捷的包（如slices、maps）。</p>
<p>更棒的是，Go官方工具链<a href="https://pkg.go.dev/golang.org/x/tools/gopls">gopls</a>（Go Language Server Protocol的实现）中，就内置了一个名为<a href="https://pkg.go.dev/golang.org/x/tools/gopls@v0.18.1/internal/analysis/modernize">modernize的分析器（Analyzer）</a>，专门用于帮助我们识别代码中可以用现代Go风格替代的“旧习”，并给出建议。</p>
<p>今天，我们就来深入了解一下gopls/modernize这个利器，看看它如何帮助我们的Go代码焕然一新，并学习一下它所倡导的11个“现代Go”风格语法要素具体包含哪些内容。</p>
<h2>1. gopls/modernize分析器以及现代Go风格简介</h2>
<p>gopls/modernize是golang.org/x/tools/gopls/internal/analysis/modernize 包提供的一个分析器。它的核心目标就是扫描你的Go代码，找出那些可以通过<a href="https://tonybai.com/2024/08/27/a-new-syntax-quiz-after-go-1-18/">使用Go 1.18及之后版本引入的新特性或标准库函数</a>来简化的代码片段。</p>
<p>modernize工具目前可以识别并建议修改多种“旧”代码模式。让我们逐一看看这些建议，并附上代码示例：</p>
<p><strong>(注：以下示例中的版本号指明了该现代写法是何时被推荐或可用的)</strong></p>
<p><strong>1). 使用min/max内建函数 (Go 1.21+)</strong></p>
<ul>
<li><strong>旧风格：</strong> 使用 if/else 进行条件赋值来找最大/最小值。</li>
</ul>
<pre><code>func findMax(a, b int) int {
    var maxVal int
    if a &gt; b {
        maxVal = a
    } else {
        maxVal = b
    }
    return maxVal
}
</code></pre>
<ul>
<li><strong>现代风格：</strong> 直接调用 max 内建函数。</li>
</ul>
<pre><code>import "cmp" // Go 1.21 implicitly uses built-ins, Go 1.22+ might suggest cmp.Or for clarity if needed

func findMaxModern(a, b int) int {
    // Go 1.21 onwards have built-in min/max
    return max(a, b)
    // Note: for floats or custom types, use cmp.Compare from "cmp" package
}
</code></pre>
<ul>
<li><strong>理由：</strong> 更简洁，意图更明确。</li>
</ul>
<p><strong>2). 使用slices.Sort (Go 1.21+)</strong></p>
<ul>
<li><strong>旧风格：</strong> 使用 sort.Slice 配合自定义比较函数对 slice 排序。</li>
</ul>
<pre><code>import "sort"

func sortInts(s []int) {
    sort.Slice(s, func(i, j int) bool {
        return s[i] &lt; s[j] // Common case for ascending order
    })
}
</code></pre>
<ul>
<li><strong>现代风格：</strong> 使用 slices.Sort 或 slices.SortFunc / slices.SortStableFunc。</li>
</ul>
<pre><code>import "slices"

func sortIntsModern(s []int) {
    slices.Sort(s) // For basic ordered types
}

// For custom comparison logic:
// func sortStructsModern(items []MyStruct) {
//     slices.SortFunc(items, func(a, b MyStruct) int {
//         return cmp.Compare(a.Field, b.Field) // Using cmp.Compare (Go 1.21+)
//     })
// }
</code></pre>
<ul>
<li><strong>理由：</strong> slices包提供了更丰富、类型更安全的排序功能，且通常性能更好。</li>
</ul>
<p><strong>3). 使用 any 替代 interface{} (Go 1.18+)</strong></p>
<ul>
<li><strong>旧风格：</strong> 使用 interface{} 表示任意类型。</li>
</ul>
<pre><code>func processAnything(v interface{}) {
    // ... process v ...
}
</code></pre>
<ul>
<li><strong>现代风格：</strong> 使用 any 类型别名。</li>
</ul>
<pre><code>func processAnythingModern(v any) {
    // ... process v ...
}
</code></pre>
<ul>
<li><strong>理由：</strong> any 是 interface{} 的官方别名，更简洁，更能体现其“任意类型”的语义。</li>
</ul>
<p><strong>4). 使用 slices.Clone 或 slices.Concat (Go 1.21+)</strong></p>
<ul>
<li><strong>旧风格：</strong> 使用 append([]T(nil), s&#8230;) 来克隆 slice。</li>
</ul>
<pre><code>func cloneSlice(s []byte) []byte {
    return append([]byte(nil), s...)
}
</code></pre>
<ul>
<li><strong>现代风格：</strong> 使用 slices.Clone。</li>
</ul>
<pre><code>import "slices"

func cloneSliceModern(s []byte) []byte {
    return slices.Clone(s)
}
</code></pre>
<ul>
<li><strong>理由：</strong> slices.Clone 意图更明确，由标准库实现可能更优化。slices.Concat 则用于拼接多个 slice。</li>
</ul>
<p><strong>5). 使用 maps 包函数 (Go 1.21+)</strong></p>
<ul>
<li><strong>旧风格：</strong> 手动写循环来拷贝或操作 map。</li>
</ul>
<pre><code>func copyMap(src map[string]int) map[string]int {
    dst := make(map[string]int, len(src))
    for k, v := range src {
        dst[k] = v
    }
    return dst
}
</code></pre>
<ul>
<li><strong>现代风格：</strong> 使用 maps.Clone 或 maps.Copy。</li>
</ul>
<pre><code>import "maps"

func copyMapModern(src map[string]int) map[string]int {
    return maps.Clone(src) // Clone creates a new map
}

func copyMapToExisting(dst, src map[string]int) {
     maps.Copy(dst, src) // Copy copies key-values, potentially overwriting
}
</code></pre>
<ul>
<li><strong>理由：</strong> maps 包提供了标准化的 map 操作，代码更简洁，不易出错。还有 maps.DeleteFunc, maps.Equal 等实用函数。</li>
</ul>
<p><strong>6). 使用 fmt.Appendf (Go 1.19+)</strong></p>
<ul>
<li><strong>旧风格：</strong> 使用 []byte(fmt.Sprintf(&#8230;)) 来获取格式化后的字节 slice。</li>
</ul>
<pre><code>import "fmt"

func formatToBytes(id int, name string) []byte {
    s := fmt.Sprintf("ID=%d, Name=%s", id, name)
    return []byte(s)
}
</code></pre>
<ul>
<li><strong>现代风格：</strong> 使用 fmt.Appendf，通常配合 nil 作为初始 slice。</li>
</ul>
<pre><code>import "fmt"

func formatToBytesModern(id int, name string) []byte {
    // Appends formatted string directly to a byte slice
    return fmt.Appendf(nil, "ID=%d, Name=%s", id, name)
}
</code></pre>
<ul>
<li><strong>理由：</strong> fmt.Appendf 更高效，它避免了先生成 string 再转换成 []byte 的中间步骤和内存分配。</li>
</ul>
<p><strong>7). 在测试中使用 t.Context (Go 1.24+)</strong></p>
<ul>
<li><strong>旧风格：</strong> 在测试函数中需要 cancellable context 时，使用 context.WithCancel。</li>
</ul>
<pre><code>import (
    "context"
    "testing"
    "time"
)

func TestSomethingWithContext(t *testing.T) {
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    // Use ctx in goroutines or functions that need cancellation
    go func(ctx context.Context) {
        select {
        case &lt;-time.After(1 * time.Second):
            t.Log("Worker finished")
        case &lt;-ctx.Done():
            t.Log("Worker cancelled")
        }
    }(ctx)

    // Simulate test work
    time.Sleep(100 * time.Millisecond)
    // Maybe cancel based on some condition, or rely on defer cancel() at end
}
</code></pre>
<ul>
<li><strong>现代风格：</strong> 直接使用 testing.T 提供的 Context() 方法。</li>
</ul>
<pre><code>import (
    "context"
    "testing"
    "time"
)

func TestSomethingWithContextModern(t *testing.T) {
    // t.Context() is automatically cancelled when the test (or subtest) finishes.
    // It may also be cancelled sooner if the test times out (e.g., using t.Deadline()).
    ctx := t.Context()

    go func(ctx context.Context) {
        select {
        case &lt;-time.After(1 * time.Second):
            t.Log("Worker finished")
        case &lt;-ctx.Done():
            t.Logf("Worker cancelled: %v", ctx.Err()) // Good practice to log the error
        }
    }(ctx)

    time.Sleep(100 * time.Millisecond)
}
</code></pre>
<ul>
<li><strong>理由：</strong> t.Context() 更方便，自动管理 context 的生命周期与测试的生命周期绑定，减少了样板代码，并能正确处理测试超时。</li>
</ul>
<p><strong>8). 使用 omitzero 代替 omitempty (Go 1.24+)</strong></p>
<ul>
<li><strong>旧风格：</strong> 在 json 或类似 tag 中使用 omitempty，它会在字段值为其类型的零值（如 0, “”, nil, 空 slice/map）时省略该字段。但对于空结构体字段则表现不如预期：</li>
</ul>
<pre><code>type ConfigOld struct {
    EmptyStruct struct{} `json:",omitempty"`
}

// JSON 输出为 {"EmptyStruct":{}}
</code></pre>
<ul>
<li><strong>现代风格：</strong> 如果意图是“当字段值为零值时省略”，则使用 omitzero。</li>
</ul>
<pre><code>type ConfigModern struct {
    EmptyStruct struct{} `json:",omitzero"`
}
// JSON 输出为 {}
</code></pre>
<ul>
<li><strong>理由：</strong> omitzero 的语义更精确地描述了“省略零值”的行为。更多内容，可以参考我的“<a href="https://tonybai.com/2024/09/12/solve-the-empty-value-dilemma-in-json-encoding-with-omitzero">JSON包新提案：用“omitzero”解决编码中的空值困局</a>”一文。</li>
</ul>
<p><strong>9). 使用 slices.Delete (Go 1.21+)</strong></p>
<ul>
<li><strong>旧风格：</strong> 使用 append(s[:i], s[i+1]&#8230;) 来删除 slice 中的单个元素。</li>
</ul>
<pre><code>func deleteElement(s []int, i int) []int {
    if i &lt; 0 || i &gt;= len(s) {
        return s // Index out of bounds
    }
    return append(s[:i], s[i+1:]...)
}
</code></pre>
<ul>
<li><strong>现代风格：</strong> 使用 slices.Delete 删除一个或一段元素。</li>
</ul>
<pre><code>import "slices"

func deleteElementModern(s []int, i int) []int {
    if i &lt; 0 || i &gt;= len(s) {
        return s
    }
    // Delete element at index i
    return slices.Delete(s, i, i+1)
}

func deleteElementsModern(s []int, start, end int) []int {
     // Delete elements from index start (inclusive) to end (exclusive)
     return slices.Delete(s, start, end)
}
</code></pre>
<ul>
<li><strong>理由：</strong> slices.Delete 意图更明确，更通用（可以删除区间），由标准库实现可能更健壮（处理边界情况）。</li>
</ul>
<p><strong>10). 使用for range n (Go 1.22+)</strong></p>
<ul>
<li><strong>旧风格：</strong> 使用经典的三段式 for 循环遍历 0 到 n-1。</li>
</ul>
<pre><code>func iterateN(n int) {
    for i := 0; i &lt; n; i++ {
        // Use i
        _ = i
    }
}
</code></pre>
<ul>
<li><strong>现代风格：</strong> 使用 for range 遍历整数。</li>
</ul>
<pre><code>func iterateNModern(n int) {
    for i := range n { // Requires Go 1.22+
        // Use i
         _ = i
    }
}
</code></pre>
<ul>
<li><strong>理由：</strong> 语法更简洁。在某些情况下（虽然不常见），如果循环体没有使用 i，for range n 可能比 for i:=0; i&lt;n; i++ 有微弱的性能优势（避免迭代变量的开销）。</li>
</ul>
<p><strong>11). 使用 strings.SplitSeq (Go 1.24+)</strong></p>
<ul>
<li><strong>旧风格：</strong> 在循环中迭代 strings.Split 的结果。</li>
</ul>
<pre><code>import "strings"

func processSplits(s, sep string) {
    parts := strings.Split(s, sep)
    for _, part := range parts {
        // Process part
        _ = part
    }
}
</code></pre>
<ul>
<li><strong>现代风格：</strong> 如果只是为了迭代，推荐使用 strings.SplitSeq（如果 Go 版本支持）。</li>
</ul>
<pre><code>import "strings"

func processSplitsModern(s, sep string) {
    // SplitSeq returns an iterator, potentially more efficient
    // as it doesn't necessarily allocate the slice for all parts at once.
    for part := range strings.SplitSeq(s, sep) { // Requires Go 1.24+
        // Process part
         _ = part
    }
}
</code></pre>
<ul>
<li><strong>理由：</strong> strings.SplitSeq 返回一个迭代器 (iter.Seq[string])，它在迭代时才切分字符串，避免了一次性分配存储所有子串的 slice 的开销，对于大字符串和/或大量子串的情况，内存效率更高。</li>
</ul>
<h2>2. 为什么要拥抱“现代Go”风格？</h2>
<p>通过前面modernize工具支持的现代风格的示例，我们大致可以得到三点采用现代Go风格的好处：</p>
<ul>
<li><strong>代码更简洁、可读性更高：</strong> 新的语言特性或标准库函数往往能用更少的代码、更清晰地表达意图。</li>
<li><strong>利用标准库优化：</strong> slices、maps等新包通常经过精心设计和优化，性能和健壮性可能优于手写的等效逻辑。</li>
<li><strong>与时俱进，降低维护成本：</strong> 使用社区和官方推荐的新方式，有助于保持代码库的技术先进性，也便于团队成员（尤其是新人）理解和维护。</li>
</ul>
<p>认识到拥抱“现代 Go”风格的诸多好处，自然会问：如何使用modern工具才能帮助我们识别并实践这些风格呢？接下来我们就来看看modernize工具的用法。</p>
<h2>3. 如何在你的项目中使用 modernize</h2>
<p>modernize工具本身是一个命令行程序。你可以通过以下方式在你的项目根目录下运行它：</p>
<pre><code>$go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest [flags] [package pattern]
</code></pre>
<ul>
<li>[package pattern]：指定要扫描的包，通常我们会使用 ./&#8230; 来扫描当前目录及其所有子目录下的包。</li>
<li>[flags]：一些常用的标志：
<ul>
<li>-test (boolean, default true)：是否分析测试文件 (_test.go)。默认是分析的。</li>
<li>-fix (boolean, default false)：自动应用所有建议的修复。<strong>请谨慎使用，建议先人工检查或在版本控制下使用。</strong></li>
<li>-diff (boolean, default false)：如果同时使用了 -fix，此标志会让工具不直接修改文件，而是打印出 unified diff 格式的变更内容，方便预览。</li>
</ul>
</li>
</ul>
<p><strong>执行示例：</strong></p>
<p>正如我在我的两个开源项目<a href="https://tonybai.com/2025/03/04/deep-dive-into-gocacheprog-custom-extensions-for-go-build-cache/">go-cache-prog</a>和<a href="https://github.com/bigwhite/local-gitingest">local-gitingest</a>中尝试的那样：</p>
<pre><code>➜  /Users/tonybai/go/src/github.com/bigwhite/go-cache-prog git:(main) $ go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest -test ./...
/Users/tonybai/go/src/github.com/bigwhite/go-cache-prog/cmd/go-cache-prog/main.go:19:2: Loop can be simplified using slices.Contains
exit status 3

➜  /Users/tonybai/go/src/github.com/bigwhite/local-gitingest git:(main) ✗ $ go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest -test ./...
/Users/tonybai/go/src/github.com/bigwhite/local-gitingest/main_test.go:191:5: Loop can be simplified using slices.Contains
exit status 3
</code></pre>
<p>我们看到modernize的输出格式为：</p>
<pre><code>文件路径:行号:列号: 建议信息。
</code></pre>
<p>这里的 exit status 3 通常表示 Linter 发现了问题。它提示我在这两个项目的指定位置，存在一个循环可以用 slices.Contains 来简化（这也是 modernize 支持的一个检查，虽然未在上述重点说明的现代风格列表中，但也属于简化代码的范畴）。</p>
<p><strong>注意：</strong> 工具的文档提到，如果修复之间存在冲突（比如一个修复改变了代码结构，使得另一个修复不再适用或需要调整），你可能需要运行 -fix 多次，直到没有新的修复被应用。</p>
<p><strong>IDE 集成：</strong></p>
<p>好消息是，如果你在使用 VS Code、GoLand 等配置了 gopls 的现代 Go IDE，很多 modernize 提出的建议通常会直接以代码高亮或建议（Quick Fix / Intention Action）的形式出现在你的编辑器中，让你可以在编码时就实时地进行现代化改造。</p>
<p>掌握了如何在项目中使用 modernize 工具后，让我们回到最初的话题，对这个工具及其倡导的“现代 Go”风格做一些思考和总结。</p>
<h2>4. 小结</h2>
<p>gopls/modernize不仅仅是一个代码检查工具，它更像是Go语言演进过程中的一个向导，温和地提醒我们：“嘿，这里有更现代、可能更好的写法了！”</p>
<p>拥抱“现代 Go”风格，利用好 modernize 这样的工具，不仅能让我们的代码库保持活力，也能促使我们不断学习和掌握 Go 的新知识。这与当年拥抱“现代 C++”的精神是一脉相承的。</p>
<p>建议大家不妨在自己的项目上运行一下 modernize 工具，看看它能给你带来哪些惊喜和改进建议。也欢迎在评论区分享你使用 modernize 的经验或对“现代 Go”风格的看法！觉得这篇文章有用？点个‘在看’，分享给更多Gopher吧！</p>
<p><strong>免责声明:</strong> modernize 工具及其命令行接口 golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize 目前并非官方稳定支持的接口，未来可能会有变动。使用 -fix 功能前请务必备份或确保代码已提交到版本控制系统。</p>
<hr />
<p><strong>原「Gopher部落」已重装升级为「Go &amp; AI 精进营」知识星球，快来加入星球，开启你的技术跃迁之旅吧！</strong></p>
<p>我们致力于打造一个高品质的 <strong>Go 语言深度学习</strong> 与 <strong>AI 应用探索</strong> 平台。在这里，你将获得：</p>
<ul>
<li><strong>体系化 Go 核心进阶内容:</strong> 深入「Go原理课」、「Go进阶课」、「Go避坑课」等独家深度专栏，夯实你的 Go 内功。</li>
<li><strong>前沿 Go+AI 实战赋能:</strong> 紧跟时代步伐，学习「Go+AI应用实战」、「Agent开发实战课」，掌握 AI 时代新技能。</li>
<li><strong>星主 Tony Bai 亲自答疑:</strong> 遇到难题？星主第一时间为你深度解析，扫清学习障碍。</li>
<li><strong>高活跃 Gopher 交流圈:</strong> 与众多优秀 Gopher 分享心得、讨论技术，碰撞思想火花。</li>
<li><strong>独家资源与内容首发:</strong> 技术文章、课程更新、精选资源，第一时间触达。</li>
</ul>
<p>衷心希望「Go &amp; AI 精进营」能成为你学习、进步、交流的港湾。让我们在此相聚，享受技术精进的快乐！欢迎你的加入！</p>
<p><img src="http://image.tonybai.com/img/tonybai/gopher-and-ai-tribe-zsxq-small-card.jpg" alt="img{512x368}" /><br />
<img src="http://image.tonybai.com/img/tonybai/go-programming-from-beginner-to-master-qr.png" alt="img{512x368}" /><br />
<img src="http://image.tonybai.com/img/tonybai/go-first-course-banner.png" alt="img{512x368}" /></p>
<p>著名云主机服务厂商DigitalOcean发布最新的主机计划，入门级Droplet配置升级为：1 core CPU、1G内存、25G高速SSD，价格6$/月。有使用DigitalOcean需求的朋友，可以打开这个<a href="https://m.do.co/c/bff6eed92687">链接地址</a>：https://m.do.co/c/bff6eed92687 开启你的DO主机之路。</p>
<p>Gopher Daily(Gopher每日新闻) &#8211; https://gopherdaily.tonybai.com</p>
<p>我的联系方式：</p>
<ul>
<li>微博(暂不可用)：https://weibo.com/bigwhite20xx</li>
<li>微博2：https://weibo.com/u/6484441286</li>
<li>博客：tonybai.com</li>
<li>github: https://github.com/bigwhite</li>
<li>Gopher Daily归档 &#8211; https://github.com/bigwhite/gopherdaily</li>
<li>Gopher Daily Feed订阅 &#8211; https://gopherdaily.tonybai.com/feed</li>
</ul>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。</p>
<p style='text-align:left'>&copy; 2025, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2025/04/15/embrace-modern-go-style-with-gopls-modernize/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
