<?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; vscode</title>
	<atom:link href="http://tonybai.com/tag/vscode/feed/" rel="self" type="application/rss+xml" />
	<link>https://tonybai.com</link>
	<description>一个程序员的心路历程</description>
	<lastBuildDate>Sun, 12 Apr 2026 22:30:28 +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>TypeScript 编译器 Go 重写版提速 10 倍：微软团队深度揭秘幕后工程细节</title>
		<link>https://tonybai.com/2026/01/27/typescript-compiler-go-rewrite-10x-speed-microsoft-details/</link>
		<comments>https://tonybai.com/2026/01/27/typescript-compiler-go-rewrite-10x-speed-microsoft-details/#comments</comments>
		<pubDate>Mon, 26 Jan 2026 23:21:49 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[AbstractSyntaxTree]]></category>
		<category><![CDATA[ast]]></category>
		<category><![CDATA[async]]></category>
		<category><![CDATA[Compiler]]></category>
		<category><![CDATA[Concurrency]]></category>
		<category><![CDATA[Consstring]]></category>
		<category><![CDATA[CrossPlatform]]></category>
		<category><![CDATA[electron]]></category>
		<category><![CDATA[Figma]]></category>
		<category><![CDATA[FunctionColoring]]></category>
		<category><![CDATA[GC]]></category>
		<category><![CDATA[GenericMethods]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[GopherCon2025]]></category>
		<category><![CDATA[IndependentCheckers]]></category>
		<category><![CDATA[JakeBailey]]></category>
		<category><![CDATA[JIT优化]]></category>
		<category><![CDATA[MemoryManagement]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[NativeCode]]></category>
		<category><![CDATA[NilSafety]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[NullCoalescing]]></category>
		<category><![CDATA[OOM]]></category>
		<category><![CDATA[OptionalChaining]]></category>
		<category><![CDATA[PerformanceLeap]]></category>
		<category><![CDATA[Rewrite]]></category>
		<category><![CDATA[Selfhosting]]></category>
		<category><![CDATA[shadowing]]></category>
		<category><![CDATA[SharedMemory]]></category>
		<category><![CDATA[slack]]></category>
		<category><![CDATA[StructEmbedding]]></category>
		<category><![CDATA[TernaryOperator]]></category>
		<category><![CDATA[ts-to-go]]></category>
		<category><![CDATA[TypeChecking]]></category>
		<category><![CDATA[TypeScript]]></category>
		<category><![CDATA[TypeScript7.0]]></category>
		<category><![CDATA[UnionTypes]]></category>
		<category><![CDATA[vscode]]></category>
		<category><![CDATA[wasm]]></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>
		<category><![CDATA[单线程]]></category>
		<category><![CDATA[垃圾回收]]></category>
		<category><![CDATA[多核CPU]]></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>
		<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=5776</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2026/01/27/typescript-compiler-go-rewrite-10x-speed-microsoft-details 大家好，我是Tony Bai。 “JavaScript 是一门很棒的语言，但它并不是为了编写编译器而设计的。” 备受瞩目的 TypeScript 编译器 Go 重写版（代号 TypeScript 7.0）已经取得了惊人的 10 倍性能提升。在最近的 GopherCon 2025 上，来自 Microsoft TypeScript 团队的 Jake Bailey 带来了一场干货满满的分享，深度揭秘了这场跨语言大迁徙背后的工程挑战与技术细节。 为什么最终选择了 Go？庞大的 AST 如何在 Go 中高效表达？又是如何通过并发设计打破 Node.js 的性能枷锁的？本文将带你深入编译器内部，一探究竟。 缘起：当 JavaScript 触碰到天花板 TypeScript 自 2012 年发布以来，一直采用“自举” (Self-hosting) 的方式，即用 TypeScript 编写 TypeScript 编译器。这带来了巨大的好处：团队能第一时间吃自己的狗粮，社区贡献也极其方便。 然而，JavaScript 并不是为了编写高性能编译器而设计的。随着代码库规模的爆炸式增长（如 VS Code 的 150 万行代码），基于 Node.js 的编译器逐渐触碰到了性能天花板： [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2026/typescript-compiler-go-rewrite-10x-speed-microsoft-details-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2026/01/27/typescript-compiler-go-rewrite-10x-speed-microsoft-details">本文永久链接</a> &#8211; https://tonybai.com/2026/01/27/typescript-compiler-go-rewrite-10x-speed-microsoft-details</p>
<p>大家好，我是Tony Bai。</p>
<p>“JavaScript 是一门很棒的语言，但它并不是为了编写编译器而设计的。”</p>
<p>备受瞩目的 <a href="https://tonybai.com/2025/03/13/interview-with-anders-hejlsberg">TypeScript 编译器 Go 重写版</a>（代号 TypeScript 7.0）已经取得了惊人的 10 倍性能提升。在最近的 GopherCon 2025 上，来自 Microsoft TypeScript 团队的 Jake Bailey 带来了<a href="https://www.youtube.com/watch?v=PZm_YbE3fcA">一场干货满满的分享</a>，深度揭秘了这场跨语言大迁徙背后的工程挑战与技术细节。</p>
<p>为什么最终选择了 Go？庞大的 AST 如何在 Go 中高效表达？又是如何通过并发设计打破 Node.js 的性能枷锁的？本文将带你深入编译器内部，一探究竟。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2026/distributed-system-guide-qr.png" alt="img{512x368}" /></p>
<h2>缘起：当 JavaScript 触碰到天花板</h2>
<p>TypeScript 自 2012 年发布以来，一直采用“自举” (Self-hosting) 的方式，即用 TypeScript 编写 TypeScript 编译器。这带来了巨大的好处：团队能第一时间吃自己的狗粮，社区贡献也极其方便。</p>
<p>然而，JavaScript 并不是为了编写高性能编译器而设计的。随着代码库规模的爆炸式增长（如 VS Code 的 150 万行代码），基于 Node.js 的编译器逐渐触碰到了性能天花板：</p>
<ul>
<li><strong>单线程与内存限制</strong>：JavaScript 无法高效利用多核 CPU，且 Node.js 构建环境（如 Electron）常常面临 4GB 内存上限，导致大型项目编译时频繁 OOM。</li>
<li><strong>昂贵的对象模型</strong>：JavaScript 的对象模型开销巨大，而编译器需要创建数以百万计的 AST 节点，这对内存和 GC 都是沉重的负担。</li>
<li><strong>异步的代价</strong>：async/await 虽然方便，但带来了著名的“函数着色”问题，且 Promise 对象的分配本身就有非零的运行时开销。</li>
</ul>
<p><img src="https://tonybai.com/wp-content/uploads/2026/typescript-compiler-go-rewrite-10x-speed-microsoft-details-2.png" alt="" /></p>
<p>尽管团队已经用尽了 JIT 优化、缓存、单态化 (monomorphization) 等高级手段，但性能提升的边际效应越来越小，OOM 问题依然挥之不去。移植到另外一种语言，成为了打破僵局的唯一选择。</p>
<h2>明确目标：新编译器的硬性指标</h2>
<p>既然决定要移植到新语言，那么新语言必须解决 JavaScript 的痛点，同时不能丢失现有的优势。团队列出了几条不可妥协的硬性指标：</p>
<ol>
<li><strong>极致速度</strong>：必须编译为原生机器码 (Native Code)，摆脱解释器和 JIT 的预热开销。</li>
<li><strong>共享内存并发</strong>：这是性能翻盘的关键。新语言必须对多线程共享内存有强力支持，以便充分压榨多核性能。</li>
<li><strong>跨平台支持</strong>：必须能运行在所有主流操作系统上，最重要的是——<strong>必须能编译为 WebAssembly</strong>，以确保在浏览器环境（如 vscode.dev）中的体验。</li>
<li><strong>无缝移植</strong>：鉴于 TypeScript 没有正式的语言规范（Spec），现有的编译器实现就是事实上的规范。因此，新语言必须能够最大程度地保留原有代码的结构和逻辑，以确保行为的一致性。</li>
</ol>
<p>正是这几条苛刻的标准，将选型的范围迅速缩小。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2026/typescript-compiler-go-rewrite-10x-speed-microsoft-details-4.png" alt="" /></p>
<h2>选型：为什么是 Go？</h2>
<p><img src="https://tonybai.com/wp-content/uploads/2026/typescript-compiler-go-rewrite-10x-speed-microsoft-details-3.png" alt="" /></p>
<p>在考察了 Rust、C#、Zig 等语言后，Go 脱颖而出。Jake 透露了核心的决策逻辑：</p>
<ol>
<li><strong>带 GC 的内存管理</strong>：编译器涉及大量复杂的、循环引用的数据结构（如 AST 节点），“手动”管理内存（如 Rust）会带来巨大的心智负担和开发成本。Go 的 GC 完美契合这一需求。</li>
<li><strong>结构相似性</strong>：TypeScript 的代码风格（无类、大量函数和接口）与 Go 非常相似。这使得“移植”而非“重写”成为可能。</li>
<li><strong>学习曲线平缓</strong>：团队中大部分是 TypeScript 专家而非系统编程专家。Go 的简单性让团队能迅速上手。</li>
<li><strong>跨平台与性能</strong>：Go 编译为原生机器码，天生支持高并发，且能轻松跨平台（包括编译为 WASM）。</li>
</ol>
<p>Go完美地契合了TypeScript编译器移植的需求！</p>
<p><img src="https://tonybai.com/wp-content/uploads/2026/typescript-compiler-go-rewrite-10x-speed-microsoft-details-5.png" alt="" /></p>
<h2>早期验证：手写原型与意外惊喜</h2>
<p>在决定全面转向 Go 之前，团队并未贸然行动，而是采取了稳健的“原型验证”策略。</p>
<p>他们从编译器的最底层——<strong>扫描器 (Scanner) 和解析器 (Parser)</strong>——开始，尝试手工将 TypeScript 代码逐行“翻译”为 Go 代码。与此同时，为了确保决策万无一失，还有几位成员试探性地尝试了其他语言方案。</p>
<p>结果令人振奋：即使是初步的手写 Go 代码，<strong>解析速度也达到了原版的 5 倍左右！</strong></p>
<p>更重要的是，团队惊喜地发现，<strong>手写的 Go 代码在结构和逻辑上与原始的 TypeScript 代码惊人地相似</strong>。这种代码形态上的高度一致性，不仅验证了 Go 是正确的选择，更为后续大规模自动化工具的开发注入了强心剂。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2026/typescript-compiler-go-rewrite-10x-speed-microsoft-details-7.png" alt="" /></p>
<h2>移植实战：从 ts-to-go 到并发革命</h2>
<h3>1. 自动化移植工具：ts-to-go</h3>
<p>为了加速迁移，Jake 编写了一个 <a href="https://github.com/jakebailey/ts-to-go">ts-to-go</a> 工具，能将 TypeScript 代码“直译”为 Go 代码。</p>
<ul>
<li>TS 的 interface -> Go 的 interface</li>
<li>TS 的 class -> Go 的 struct + methods</li>
<li>复杂的位运算和逻辑判断 -> 自动转换为 Go 的等价写法</li>
</ul>
<p>虽然不能 100% 完美转换，但这让团队在初期就能获得一个“虽然丑但能跑”的版本，极大加速了进程。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2026/typescript-compiler-go-rewrite-10x-speed-microsoft-details-6.png" alt="" /></p>
<h3>2. 数据结构的重新设计</h3>
<p>在 JavaScript 中，对象是动态的；在 Go 中，一切皆有类型。团队不得不对 AST 的数据结构进行大刀阔斧的改革。</p>
<ul>
<li><strong>消除 interface 滥用</strong>：最初的移植版本大量使用 interface 来模拟 TS 的多态，导致了巨大的内存开销（胖指针）和 nil 检查地狱。</li>
<li><strong>拥抱 struct 嵌入</strong>：最终，他们设计了一个基础 Node 结构体，并将其嵌入到所有具体的 AST 节点中。这不仅减少了内存占用，还彻底解决了 nil 接口的问题。</li>
</ul>
<h3>3. 并发：性能提升的核心引擎</h3>
<p>这是 Go 带来的最大红利。旧的 TS 编译器是单线程的，解析、绑定、检查、生成都在一条线上排队。</p>
<p>而在 Go 版本中：</p>
<ul>
<li><strong>解析 (Parsing)</strong>：每个文件可以独立解析，完全并行。</li>
<li><strong>绑定 (Binding)</strong>：每个文件的符号绑定也是独立的，完全并行。</li>
<li><strong>类型检查 (Type Checking)</strong>：这是最难的部分，因为文件间存在复杂的依赖。团队采用了<strong>“独立检查器” (Independent Checkers)</strong> 的模式，为每组文件分配一个独立的检查器，虽然会有少量重复工作，但实现了高度的并行化。</li>
</ul>
<p><img src="https://tonybai.com/wp-content/uploads/2026/typescript-compiler-go-rewrite-10x-speed-microsoft-details-9.png" alt="" /></p>
<p>结果是惊人的：<strong>VS Code 的编译时间从 80 秒缩短到了 7 秒，速度提升超过 10 倍！</strong></p>
<p><img src="https://tonybai.com/wp-content/uploads/2026/typescript-compiler-go-rewrite-10x-speed-microsoft-details-8.png" alt="" /></p>
<h2>踩坑与优化：Go 也没那么简单</h2>
<p>当然，移植过程并非一帆风顺。Jake 分享了几个典型的“水土不服”案例：</p>
<ul>
<li><strong>影子变量 (Shadowing)</strong>：Go 允许在内层作用域遮蔽外层变量（如 err、result等），这导致了无数隐蔽的 Bug。Jake 甚至为此专门写了一个静态分析工具(https://jakebailey.dev/posts/go-shadowing)来抓这些虫子。</li>
<li><strong>方法值的分配</strong>：在 Go 中，将方法作为值传递（如 parser.LookAhead）会产生一次内存分配。在一个频繁调用的紧密循环中，这带来了 17% 的性能损耗。解决方案是改回显式的函数调用。</li>
<li><strong>字符串拼接</strong>：JavaScript 引擎对字符串拼接有深度优化（Cons-string），而 Go 的 + 操作符则是实打实的内存拷贝。这导致初期的移植版本在处理大量字符串时性能惨不忍睹。</li>
</ul>
<h2>遗憾与取舍：那些我们怀念的 TypeScript 特性</h2>
<p>正如 Jake 在演讲中所言，这次迁移是一场巨大的工程胜利，但也是一次充满妥协的旅程。从表达力丰富的 TypeScript 转向“极简主义”的 Go，团队不得不忍痛割爱，放弃了许多令人怀念的语言特性：</p>
<ul>
<li><strong>编译期空值安全 (Compile-time nil safety)</strong>：这是团队最怀念的特性。在 Go 中，空指针异常（Panic）依然是悬在头顶的达摩克利斯之剑，而在 TypeScript 中，null/undefined 是类型系统的一部分，能被编译器严格检查。</li>
<li><strong>空值合并与链式调用 (??, ?.)</strong>：Go 缺乏这些语法糖，使得代码中充斥着冗长的 if x != nil 检查，远不如 TypeScript 优雅。</li>
<li><strong>联合类型与类型收窄 (Union types, narrowing)</strong>：TypeScript 强大的联合类型让数据建模极其灵活，而在 Go 中，这不得不退化为接口或带有大量字段的结构体。</li>
<li><strong>泛型方法与三元运算符</strong>：这些“现代化”特性的缺失，让从前端背景转过来的工程师们颇感不适。</li>
</ul>
<p>然而，对于编译器团队来说，<strong>为了性能，这一切“阵痛”都是值得的</strong>。他们用语法的繁琐换取了运行时的极速，这正是工程世界中最经典的“等价交换”。</p>
<blockquote>
<p>注：<a href="https://tonybai.com/2026/01/24/go-generics-finally-supports-generic-methods">关于泛型方法，Go团队很大可能将在Go 1.27支持！</a></p>
</blockquote>
<h2>未来展望：TypeScript 7.0</h2>
<p>目前，Go 版本的编译器已经能通过 10 万个测试用例，并在 Slack、Figma 等大厂的内部构建中试运行（Slack 的构建时间从 6 分钟降至 40 秒）。</p>
<p>Microsoft 计划在 TypeScript 6.0 中开始引入一些破坏性变更，为 Go 版本的上位做铺垫。而那个完全由 Go 驱动、极速的编译器，预计将被命名为 <strong>TypeScript 7.0</strong>。</p>
<p>这场从 Node.js 到 Go 的大迁徙，不仅证明了 Go 在复杂编译器领域的工程能力，也为所有面临类似性能瓶颈的团队，提供了一个极具参考价值的范本。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2026/typescript-compiler-go-rewrite-10x-speed-microsoft-details-10.png" alt="" /></p>
<blockquote>
<p>注：微软在2025年12月初发布了TypeScript 7.0的最新进展，大家可以在 https://devblogs.microsoft.com/typescript/progress-on-typescript-7-december-2025/ 这里了解详情。</p>
</blockquote>
<p>资料链接：https://www.youtube.com/watch?v=PZm_YbE3fcA</p>
<hr />
<p><strong>你的“重写”冲动</strong></p>
<p>微软用 Go 重写 TS 编译器，是一次壮士断腕般的成功尝试。<strong>在你维护的项目中，是否有那个让你想要“推倒重来”的性能瓶颈？如果让你选，你会<br />
用 Go 还是 Rust 来重写它？</strong></p>
<p><strong>欢迎在评论区分享你的重构经历或选型思考！</strong> 让我们一起探讨如何在性能与开发效率之间找到平衡。</p>
<p><strong>如果这篇文章让你对 Go 在大型项目中的潜力有了新的认识，别忘了点个【赞】和【在看】，并转发给你的架构师朋友！</strong></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>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求，请扫描下方公众号二维码，与我私信联系。</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/01/27/typescript-compiler-go-rewrite-10x-speed-microsoft-details/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>dingo：Go 语言的 “TypeScript”时刻？—— 一场由社区驱动的语言演进实验</title>
		<link>https://tonybai.com/2025/11/27/dingo-go-typescript-moment/</link>
		<comments>https://tonybai.com/2025/11/27/dingo-go-typescript-moment/#comments</comments>
		<pubDate>Wed, 26 Nov 2025 23:56:34 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[AbstractSyntaxTree]]></category>
		<category><![CDATA[ast]]></category>
		<category><![CDATA[CodeGeneration]]></category>
		<category><![CDATA[dingo]]></category>
		<category><![CDATA[enum]]></category>
		<category><![CDATA[Enums]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[go/parser]]></category>
		<category><![CDATA[go/printer]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[Gopher]]></category>
		<category><![CDATA[gopls]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[LSP]]></category>
		<category><![CDATA[match]]></category>
		<category><![CDATA[Meta-language]]></category>
		<category><![CDATA[nil]]></category>
		<category><![CDATA[NullCoalescing]]></category>
		<category><![CDATA[option]]></category>
		<category><![CDATA[panic]]></category>
		<category><![CDATA[Patternmatching]]></category>
		<category><![CDATA[PluginSystem]]></category>
		<category><![CDATA[Preprocessor]]></category>
		<category><![CDATA[Result]]></category>
		<category><![CDATA[Rust]]></category>
		<category><![CDATA[SafeNavigation]]></category>
		<category><![CDATA[simplicity]]></category>
		<category><![CDATA[SourceMaps]]></category>
		<category><![CDATA[SumTypes]]></category>
		<category><![CDATA[TypeScript]]></category>
		<category><![CDATA[vscode]]></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=5446</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/11/27/dingo-go-typescript-moment 大家好，我是Tony Bai。 Go 语言自诞生以来，以其极简主义哲学（Simplicity）赢得了全球开发者的青睐。然而，这种极简也伴随着长期的痛点： 满屏的 if err != nil。 缺失的和类型（Sum Types/Enums），导致状态表达含糊。 nil 指针带来的运行时 panic 风险。 泛型虽已到来，但函数式编程体验（如 map/filter）依然匮乏。 在每年的 Go User Survey 中，这些问题总是名列前茅。 Gopher们渴望“越狱”，但Go 核心团队对此保持审慎，这不仅是为了保持语言的纯粹，也是为了向后兼容。 一个名为dingo 的开源项目的出现，试图打破这一僵局。它自称是 “逃逸的 Go”（Go that escaped）。就像 TypeScript 之于 JavaScript，dingo 试图在不改变 Go 运行时、不引入额外依赖的前提下，通过编译时转译，为 Gopher 们提供现代化的语法糖和类型安全。 在本文中，我们就来深入剖析 dingo 的核心机制与创新语法，看看它是如何在保持 Go 零运行时开销的同时，实现那些 Gopher 们梦寐以求的现代语言特性的。 dingo 是什么？ 简单来说，dingo 是一门元语言（Meta-language）。它拥有类似 Rust 或 TypeScript [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2025/dingo-go-typescript-moment-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/11/27/dingo-go-typescript-moment">本文永久链接</a> &#8211; https://tonybai.com/2025/11/27/dingo-go-typescript-moment</p>
<p>大家好，我是Tony Bai。</p>
<p>Go 语言自诞生以来，以其极简主义哲学（Simplicity）赢得了全球开发者的青睐。然而，这种极简也伴随着长期的痛点：</p>
<ul>
<li>满屏的 if err != nil。</li>
<li>缺失的<a href="https://tonybai.com/2025/10/30/type-theory-intro-for-gopher">和类型（Sum Types/Enums）</a>，导致状态表达含糊。</li>
<li>nil 指针带来的运行时 panic 风险。</li>
<li>泛型虽已到来，但函数式编程体验（如 map/filter）依然匮乏。</li>
</ul>
<p>在每年的 Go User Survey 中，这些问题总是名列前茅。</p>
<p>Gopher们渴望“越狱”，但Go 核心团队对此保持审慎，这不仅是为了保持语言的纯粹，也是为了向后兼容。</p>
<p>一个名为<a href="https://github.com/MadAppGang/dingo">dingo</a> 的开源项目的出现，试图打破这一僵局。它自称是 <strong>“逃逸的 Go”（Go that escaped）</strong>。就像 TypeScript 之于 JavaScript，dingo 试图在不改变 Go 运行时、不引入额外依赖的前提下，通过编译时转译，为 Gopher 们提供<strong>现代化的语法糖</strong>和类型安全。</p>
<p>在本文中，我们就来深入剖析 dingo 的核心机制与创新语法，看看它是如何在保持 Go 零运行时开销的同时，实现那些 Gopher 们梦寐以求的现代语言特性的。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/paid/google-adk-in-action-qr.png" alt="" /></p>
<h2>dingo 是什么？</h2>
<p>简单来说，dingo 是一门<strong>元语言（Meta-language）</strong>。它拥有类似 Rust 或 TypeScript 的现代语法，但最终会被编译成<strong>纯粹的、符合惯例的 Go 代码</strong>。</p>
<p>其核心价值主张包括：</p>
<ol>
<li><strong>零运行时开销</strong>：编译产物就是标准的 Go 代码，性能与原生 Go 完全一致。</li>
<li><strong>向后兼容</strong>：可以直接引入现有的 Go 包，生成的代码也可以被其他 Go 项目引用。</li>
<li><strong>类型安全增强</strong>：引入 Option 和 Result 类型，语法层面消灭空指针异常。</li>
<li><strong>人体工程学升级</strong>：通过?操作符和模式匹配(Pattern matching)，大幅减少样板代码。</li>
</ol>
<blockquote>
<p>注：为什么叫 dingo（澳洲野犬）？dingo项目的README 中有一个有趣的隐喻：Go 的吉祥物 Gopher（地鼠）是规矩的、被管理的；而 dingo（澳洲野犬）曾是家犬，后来逃入荒野，恢复了野性。dingo 语言依然保留了 Go 的基因，但它拒绝被传统的规则束缚——它代表了<strong>未经许可的自由</strong>。</p>
</blockquote>
<hr />
<h2>核心特性与代码对比</h2>
<p>dingo 并非为了标新立异，而是为了解决实际问题。以下是它如何通过转译解决 Go 的四大痛点：</p>
<h3>错误传播：告别 if err != nil</h3>
<p>Go 的错误处理不仅啰嗦，而且容易打断阅读逻辑。dingo 引入了类似 Rust 的 ? 操作符。</p>
<p><strong>dingo 写法：</strong></p>
<pre><code class="go">// 看起来像 Rust，实际上是 Go 的超集
func processOrder(orderID: string) -&gt; Result&lt;Order, Error&gt; {
    let order = fetchOrder(orderID)?          // 如果出错，直接返回 Err
    let validated = validateOrder(order)?     // 自动解包 Ok 的值
    let payment = processPayment(validated)?
    return Ok(payment)
}
</code></pre>
<p><strong>转译后的 Go 代码（自动生成）：</strong></p>
<pre><code class="go">func processOrder(orderID string) (Order, error) {
    order, err := fetchOrder(orderID)
    if err != nil {
        return Order{}, err
    }

    validated, err := validateOrder(order)
    if err != nil {
        return Order{}, err
    }
    // ...以此类推
}
</code></pre>
<p>我们从上面示例代码的字面上就能看到收益：样板代码减少约 67%，业务逻辑一目了然。</p>
<h3>Sum类型与模式匹配</h3>
<p>这是 Go 社区呼声最高的功能之一（[Proposal #19412](在本文中，我们就来深入剖析 Dingo 的核心机制与创新语法，看看它如何在保持 Go 零运行时开销的同时，实现那些 Gopher 们梦寐以求的现代语言特性。)）。dingo 通过 enum 和 match 完美实现了这一点。</p>
<p><strong>dingo 写法：</strong></p>
<pre><code class="go">enum Shape {
    Circle { radius: float64 },
    Rectangle { width: float64, height: float64 },
    Point,
}

func area(s: Shape) -&gt; float64 {
    match s {
        Circle(r) =&gt; 3.14 * r * r,
        Rectangle(w, h) =&gt; w * h,
        Point =&gt; 0.0
    }
}
</code></pre>
<p>dingo 将 enum 转译为 Go 的 struct + tag（标签联合体），并生成辅助方法（如 IsCircle(), NewCircle()）。match 语句在编译时会进行<strong>穷尽性检查</strong>（Exhaustiveness Checking），如果你漏掉了一种情况，编译就会报错。</p>
<h3>3. 空值安全</h3>
<p>受 Swift 和 Kotlin 启发，dingo 引入了安全导航(Safe navigation)操作符 ?. 和空值合并操作符 ??。</p>
<p><strong>dingo 写法：</strong></p>
<pre><code class="go">// 还在写嵌套的 nil 检查吗？
let city = user?.address?.city?.name ?? "Unknown"
</code></pre>
<p><strong>转译后的 Go 代码：</strong></p>
<p>这会被展开为一系列的 if 检查或立即执行函数表达式，确保不会发生 panic。</p>
<h3>4. 函数式编程工具</h3>
<p><strong>dingo 写法：</strong></p>
<pre><code class="go">let numbers = []int{1, 2, 3, 4, 5}
let doubled = numbers.filter(|x| x % 2 == 0).map(|x| x * 2)
</code></pre>
<p>支持 TypeScript 风格的箭头函数 (=>) 或 Rust 风格的管道符 (||)。</p>
<hr />
<h2>技术架构与实现原理</h2>
<p>dingo 的实现非常务实，它没有重写整个 Go 编译器，而是采用了<strong>两阶段转译架构</strong>：</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/dingo-go-typescript-moment-2.png" alt="" /></p>
<h3>编译器架构</h3>
<ul>
<li><strong>Stage 1: 预处理器 (Preprocessor)</strong>
<ul>
<li>处理 dingo 特有的语法糖（如 ? 操作符、enum 定义、类型注解 : Type）。</li>
<li>使用基于正则和文本的转换，将 dingo 代码转换为“合法的”但包含特殊标记的 Go 代码。</li>
</ul>
</li>
<li><strong>Stage 2: AST 转换 (Plugin System)</strong>
<ul>
<li>利用 Go 原生的 go/parser 解析代码。</li>
<li>通过插件系统（Plugins）对 AST（抽象语法树）进行语义层面的转换。例如，将 Result<T> 展开为具体的 struct 定义。</li>
</ul>
</li>
<li><strong>Code Generation</strong>: 最后使用 go/printer 输出格式化好的 Go 代码。</li>
</ul>
<h3>IDE 支持的秘密武器：Source Maps</h3>
<p>许多转译语言失败的原因是调试体验差——报错指向生成的代码，而不是源码。</p>
<p>dingo 实现了<strong>精确的 Source Maps (v1 格式)</strong>。</p>
<ul>
<li>它建立 .dingo 文件和生成 .go 文件之间的双向映射。</li>
<li><strong>LSP 集成</strong>：dingo 开发了一个 LSP 代理（Proxy），它包装了官方的 gopls。当你请求“跳转定义”时，代理拦截请求，利用 Source Map 将位置从 dingo 坐标转换到 Go 坐标，发送给 gopls，拿到结果后再转换回来。这样，你在 VS Code 中写 dingo，享受的是 Go 级别的智能提示和重构能力。</li>
</ul>
<h3>混合包管理策略</h3>
<p>dingo 采用了一种聪明的混合策略来解决生态兼容性：</p>
<ul>
<li><strong>应用开发</strong>：保留 .dingo 文件，忽略生成的 .go 文件。开发体验类似 TypeScript。</li>
<li><strong>库开发</strong>：在发布时，将 .dingo 转译为 .go 并提交到版本控制系统。</li>
<li><strong>意义</strong>：任何纯 Go 项目都可以 go get 一个用 dingo 写的库，而不需要安装 dingo。这是生态融合的关键。</li>
</ul>
<hr />
<h2>哲学与争议：为什么这很重要？</h2>
<p>dingo 的 项目说明文档中提出了一个深刻的观点：<strong>“自私地使用 dingo，顺便推动 Go 的演进。”</strong></p>
<p>TypeScript 最初并非为了改变 JavaScript 标准，而是为了让开发者在大项目中活下来。但随着 TS 的普及（Async/Await, Optional Chaining），这些特性最终被吸纳进 ECMAScript 标准。</p>
<p>dingo的对 Go 核心团队的参考价值，和TS类似。</p>
<p>Go 核心团队在引入新特性时非常依赖“证据”而非“理论”。 Proposal #19412 尚未被accept，是因为缺乏 Go 语境下的具体实现范例。但 dingo 如果能拥有 5 万开发者，它就提供了一份<strong>实证数据</strong>：</p>
<ul>
<li>“使用了 ? 操作符的项目，代码量减少了 X%。”</li>
<li>“和类型在 Go 的 runtime 上运行良好，并没有导致性能下降。”</li>
</ul>
<p>因此，<strong>dingo 不是 Go 的竞争者，它是 Go 未来的沙盒。</strong></p>
<hr />
<h2>上手指南与现状</h2>
<p>目前，截至本文编写时， dingo 还处于 <strong><a href="https://github.com/MadAppGang/dingo/releases/tag/v0.3.0">v0.3.0-alpha</a></strong> 阶段，主要核心特性（Sum类型、模式匹配、错误传播、LSP 支持）完成度还不高，仅适合向往拥有Rust、TypeScript等表达力更强的语法的Gopher尝鲜体验之用。</p>
<h3>快速安装</h3>
<pre><code class="bash"># 克隆仓库并构建编译器
git clone https://github.com/MadAppGang/dingo.git 或 git clone --depth=1 git@github.com:MadAppGang/dingo.git
cd dingo &amp;&amp; go build -o dingo ./cmd/dingo

# 将 dingo 加入环境变量 (可选)
export PATH=$PATH:$(pwd)
</code></pre>
<p>验证安装结果：</p>
<pre><code># dingo version
</code></pre>
<p><img src="https://tonybai.com/wp-content/uploads/2025/dingo-go-typescript-moment-3.png" alt="" /></p>
<h3>Hello World</h3>
<pre><code class="bash"># 编写 hello.dingo

package main
func main() {
    let msg = "Hello from dingo"
    println(msg)
}

# 编译并运行（dingo 会自动调用 Go 编译器）
dingo run hello.dingo
</code></pre>
<p><img src="https://tonybai.com/wp-content/uploads/2025/dingo-go-typescript-moment-4.png" alt="" /></p>
<p>运行过程中，dingo会生成转义后的hello.go代码：</p>
<pre><code>package main

func main() {
        msg := "Hello from dingo"
        println(msg)
}
</code></pre>
<p>大家通过转义后的代码，也可以看到它的转换过程和原理。</p>
<hr />
<h2>小结</h2>
<p>dingo 是一个大胆的实验。它证明了我们可以在不分叉 Go 语言、不分裂生态系统的前提下，拥有现代化的语言特性。</p>
<p>不过，目前<strong>dingo的完成度还非常低</strong>，很多项目自带的example都build/run failed，这也是本篇文章可以运行的示例较少的原因:(。根据作者的Roadmap，目前很多新增的语法特性还处于未完成阶段。</p>
<p>但对于 Gopher 来说，如果你厌倦了 if err != nil，将来一旦完成度上来的dingo 很值得一试。即使你坚持使用纯 Go，dingo 的存在也是一件好事——它是一只被放入沙丁鱼群的鲶鱼，或许能激活 Go 语言演进的一池春水。</p>
<p><strong>正如dingo项目宣言所说：这是你的语言，你的规则。无需委员会批准。</strong></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>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求，请扫描下方公众号二维码，与我私信联系。</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/11/27/dingo-go-typescript-moment/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Go 的甜蜜16 岁：一份来自官方的年度成绩单与未来路线图</title>
		<link>https://tonybai.com/2025/11/15/go-turns-16/</link>
		<comments>https://tonybai.com/2025/11/15/go-turns-16/#comments</comments>
		<pubDate>Sat, 15 Nov 2025 00:38:33 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[ADKGo]]></category>
		<category><![CDATA[Agent]]></category>
		<category><![CDATA[AgentDevelopmentKit]]></category>
		<category><![CDATA[AIassistant]]></category>
		<category><![CDATA[AIcodingassistants]]></category>
		<category><![CDATA[AI助手]]></category>
		<category><![CDATA[AI时代]]></category>
		<category><![CDATA[AI编码助手]]></category>
		<category><![CDATA[AI集成]]></category>
		<category><![CDATA[Anthropic]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[AustinClements]]></category>
		<category><![CDATA[AVX-512vectorinstructions]]></category>
		<category><![CDATA[CAVP]]></category>
		<category><![CDATA[codemodernizationtools]]></category>
		<category><![CDATA[compatibilitypromise]]></category>
		<category><![CDATA[containerawarescheduling]]></category>
		<category><![CDATA[CPUthrottling]]></category>
		<category><![CDATA[CPU节流]]></category>
		<category><![CDATA[encoding/json]]></category>
		<category><![CDATA[executiontracer]]></category>
		<category><![CDATA[FIPS]]></category>
		<category><![CDATA[FIPS140-3]]></category>
		<category><![CDATA[FIPS140compliance]]></category>
		<category><![CDATA[FIPS140合规性]]></category>
		<category><![CDATA[FIPS认证]]></category>
		<category><![CDATA[FlightRecorder]]></category>
		<category><![CDATA[Geomys]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[go1.0]]></category>
		<category><![CDATA[Go1.0之前的根源]]></category>
		<category><![CDATA[go1.24]]></category>
		<category><![CDATA[go1.25]]></category>
		<category><![CDATA[go1.26]]></category>
		<category><![CDATA[GoCommunity]]></category>
		<category><![CDATA[gofix]]></category>
		<category><![CDATA[gofix命令]]></category>
		<category><![CDATA[GoLanguageAdvancedCourse]]></category>
		<category><![CDATA[Golanguageentryleveltreasure]]></category>
		<category><![CDATA[Golanguagefirstlesson]]></category>
		<category><![CDATA[GoMCPSDK]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Goopensourceproject]]></category>
		<category><![CDATA[Gopher]]></category>
		<category><![CDATA[goplsfeaturedocumentation]]></category>
		<category><![CDATA[goplsfeatures]]></category>
		<category><![CDATA[goplslanguageserver]]></category>
		<category><![CDATA[goprimer]]></category>
		<category><![CDATA[goroutineleakanalysis]]></category>
		<category><![CDATA[GoTeam]]></category>
		<category><![CDATA[Go专家]]></category>
		<category><![CDATA[Go代码]]></category>
		<category><![CDATA[Go开源项目]]></category>
		<category><![CDATA[Go熟练工]]></category>
		<category><![CDATA[greentea]]></category>
		<category><![CDATA[GreenTeaGC]]></category>
		<category><![CDATA[HashTable]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[JoeTsai]]></category>
		<category><![CDATA[KnowledgePlanet]]></category>
		<category><![CDATA[LSP]]></category>
		<category><![CDATA[LSPbasededitors]]></category>
		<category><![CDATA[mapimplementation]]></category>
		<category><![CDATA[map实现]]></category>
		<category><![CDATA[MCP]]></category>
		<category><![CDATA[MCPserver]]></category>
		<category><![CDATA[ModelContextProtocol]]></category>
		<category><![CDATA[ModelContextProtocolMCP]]></category>
		<category><![CDATA[net/http]]></category>
		<category><![CDATA[officialGoSDK]]></category>
		<category><![CDATA[osRoot]]></category>
		<category><![CDATA[SIMD]]></category>
		<category><![CDATA[SIMDhardwarecapabilities]]></category>
		<category><![CDATA[staticanalysistools]]></category>
		<category><![CDATA[synctest]]></category>
		<category><![CDATA[testing/synctest]]></category>
		<category><![CDATA[testingBLoop]]></category>
		<category><![CDATA[testingBN]]></category>
		<category><![CDATA[testingTContext]]></category>
		<category><![CDATA[testingTOutput]]></category>
		<category><![CDATA[TonyBaiGolanguageadvancedcourse]]></category>
		<category><![CDATA[TrailofBits]]></category>
		<category><![CDATA[traversalresistantfilesystemaccess]]></category>
		<category><![CDATA[uber]]></category>
		<category><![CDATA[Unicode]]></category>
		<category><![CDATA[v0.17.0]]></category>
		<category><![CDATA[v0.18.0]]></category>
		<category><![CDATA[v0.19.0]]></category>
		<category><![CDATA[v0.20.0]]></category>
		<category><![CDATA[v1.0.0]]></category>
		<category><![CDATA[vscode]]></category>
		<category><![CDATA[WeChatQR]]></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>
		<category><![CDATA[官方GoSDK]]></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>
		<category><![CDATA[未来路线图]]></category>
		<category><![CDATA[标准库]]></category>
		<category><![CDATA[核心语言]]></category>
		<category><![CDATA[核心语言和库]]></category>
		<category><![CDATA[模型上下文协议]]></category>
		<category><![CDATA[泄露goroutine分析]]></category>
		<category><![CDATA[漏洞]]></category>
		<category><![CDATA[生产效率]]></category>
		<category><![CDATA[生产栈库]]></category>
		<category><![CDATA[生产系统]]></category>
		<category><![CDATA[生产级AI开发]]></category>
		<category><![CDATA[生成式AI]]></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=5390</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/11/15/go-turns-16 大家好，我是Tony Bai。 今年的 Go 官方16岁“庆生”文章，来得比以往时候都要晚一些。 往年，我们总能在 11 月 10 日或 11 日，准时收到这份来自 Go 团队的年度“家庭来信”。但今年，日历翻过了好几天，官方博客却依旧静悄悄。前几天，我还在知识星球上和星友们“抱怨”：“今年 Go 官方居然没有发 16 周年庆生纪念文章，比较反常啊！是忙忘了？还是没人有空写？” 现在回头看，这份“迟到”的生日礼物，或许恰恰反映了 Go 团队当前的状态。与其说是“忙忘了”，我更倾向于相信，这是新任技术负责人 Austin Clements 那种众所周知的严谨风格的体现——在没有将过去一年的所有重要进展都梳理清晰、打磨完美之前，宁愿延迟，也绝不仓促发文。抑或是，随着 Go 在 AI 时代的责任日益重大，团队的每一个字，都变得更加审慎和深思熟虑。 那么，这份姗姗来迟的“年度报告”，又为何值得我们全文翻译，并分享给大家呢？ 因为这不仅仅是一篇生日贺文，它更是一份极其珍贵的、信息密度极高的官方“战略简报”。 在这篇文章里，Go 团队不仅系统性地盘点了过去一年中，从核心语言、安全体系到工具链的所有重大成果（synctest, Green Tea GC, FIPS 认证, go fix&#8230;），更重要的是，它首次清晰地、成体系地阐述了 Go 在 AI 时代的定位与雄心。它告诉我们，Go 团队正在如何将 Go 语言独特的并发、性能和可靠性优势，注入到 AI 集成、Agent 和基础设施的构建中。 对于我们每一位 Gopher 而言，这篇文章就是一张官方的“藏宝图”。它不仅能帮助我们快速跟上 [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2025/go-turns-16-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/11/15/go-turns-16">本文永久链接</a> &#8211; https://tonybai.com/2025/11/15/go-turns-16</p>
<p>大家好，我是Tony Bai。</p>
<p>今年的 Go 官方16岁“庆生”文章，来得比以往时候都要晚一些。</p>
<p>往年，我们总能在 11 月 10 日或 11 日，准时收到这份来自 Go 团队的年度“家庭来信”。但今年，日历翻过了好几天，官方博客却依旧静悄悄。前几天，我还在<a href="https://public.zsxq.com/groups/51284458844544">知识星球</a>上和星友们“抱怨”：“今年 Go 官方居然没有发 16 周年庆生纪念文章，比较反常啊！是忙忘了？还是没人有空写？”</p>
<p>现在回头看，这份“迟到”的生日礼物，或许恰恰反映了 Go 团队当前的状态。与其说是“忙忘了”，我更倾向于相信，这是新任技术负责人 Austin Clements 那种众所周知的严谨风格的体现——<strong>在没有将过去一年的所有重要进展都梳理清晰、打磨完美之前，宁愿延迟，也绝不仓促发文</strong>。抑或是，随着 Go 在 AI 时代的责任日益重大，团队的每一个字，都变得更加审慎和深思熟虑。</p>
<p>那么，这份姗姗来迟的“年度报告”，又为何值得我们全文翻译，并分享给大家呢？</p>
<p><strong>因为这不仅仅是一篇生日贺文，它更是一份极其珍贵的、信息密度极高的官方“战略简报”。</strong></p>
<p>在这篇文章里，Go 团队不仅系统性地盘点了过去一年中，从核心语言、安全体系到工具链的<strong>所有重大成果</strong>（synctest, Green Tea GC, FIPS 认证, go fix&#8230;），更重要的是，它<strong>首次清晰地、成体系地阐述了 Go 在 AI 时代的定位与雄心</strong>。它告诉我们，Go 团队正在如何将 Go 语言独特的并发、性能和可靠性优势，注入到 AI 集成、Agent 和基础设施的构建中。</p>
<p>对于我们每一位 Gopher 而言，这篇文章就是一张<strong>官方的“藏宝图”</strong>。它不仅能帮助我们快速跟上 Go 的最新动态，更能让我们洞察这门语言未来的发展方向，从而在技术浪潮中，做出更明智的学习和职业决策。</p>
<p>下面，就让我们一同深入这份迟到但分量十足的“生日礼物”。以下是文章全文。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/paid/go-micro-column-2025-pr.png" alt="" /></p>
<hr />
<p>刚刚过去的周一，11 月 10 日，我们庆祝了 Go <a href="https://opensource.googleblog.com/2009/11/hey-ho-lets-go.html">开源发布</a> 16 周年！</p>
<p>我们遵循了现在已经非常成熟和可靠的发布节奏，在<a href="https://tonybai.com/2025/02/16/some-changes-in-go-1-24">二月份发布了 Go 1.24</a>，并在<a href="https://tonybai.com/2025/08/15/some-changes-in-go-1-25">八月份发布了 Go 1.25</a>。为了继续我们构建最高效的生产系统语言平台的使命，这些版本包含了用于构建健壮可靠软件的新 API，在 Go 构建安全软件的记录上取得了显著进展，以及一些重要的底层改进。与此同时，没有人能忽视生成式 AI 给我们行业带来的巨大变革。Go 团队正以深思熟虑且毫不妥协的思维方式应对这一充满活力的领域中的挑战和机遇，致力于将 Go 的生产就绪方法应用于构建健壮的 AI 集成、产品、智能体和基础设施。</p>
<h2>核心语言和库的改进</h2>
<p>新的 <a href="https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzIyNzM0MDk0Mg==&amp;action=getalbum&amp;album_id=4017357519222882315#wechat_redirect">testing/synctest</a> 包在 Go 1.24 中作为实验性功能首次发布，然后在 Go 1.25 中正式毕业，它极大地简化了为<a href="https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzIyNzM0MDk0Mg==&amp;action=getalbum&amp;album_id=4017357519222882315#wechat_redirect">并发、异步代码</a>编写测试的过程。这类代码在网络服务中尤为常见，并且传统上很难进行良好的测试。<a href="https://tonybai.com/2025/09/29/synctest-bugs-in-go-1-25/">synctest 包</a>通过虚拟化时间本身来工作。它将过去缓慢、不稳定或两者兼有的测试，转变为易于重写成可靠且几乎瞬时完成的测试，通常只需增加几行代码。这也是 Go 软件开发集成方法的一个绝佳例子：在一个几乎微不足道的 API 背后，synctest 包隐藏了与 Go 运行时和标准库其他部分的深度集成。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/paid/go-concurrent-test-qr.png" alt="img{512x368}" /></p>
<p>这并非过去一年中 testing 包得到的唯一增强。新的 <a href="https://pkg.go.dev/testing#B.Loop">testing.B.Loop</a> API 不仅比原来的 testing.B.N API 更易于使用，还解决了编写 Go 基准测试时许多传统的——且常常是不可见的！——<a href="https://go.dev/blog/testing-b-loop">陷阱</a>。testing 包还新增了 API，可以<a href="https://pkg.go.dev/testing#T.Context">轻松地在使用 Context 的测试中进行清理</a>，以及<a href="https://pkg.go.dev/testing#T.Output">轻松地向测试日志写入内容</a>。</p>
<p>Go 和容器化技术一同成长，并彼此配合得很好。Go 1.25 推出了<a href="https://tonybai.com/2025/04/09/gomaxprocs-defaults-add-cgroup-aware">容器感知调度</a>，使这对组合更加强大。开发者无需任何操作，它就能透明地调整在容器中运行的 Go 工作负载的并行度，防止可能影响尾部延迟的 CPU 节流，并提升了 Go 开箱即用的生产就绪性。</p>
<p>Go 1.25 的新<a href="https://tonybai.com/2025/07/11/net-http-pprof-v2/">飞行记录器(flight recorder)</a>建立在我们本已强大的执行追踪器之上，能够深入洞察生产系统的动态行为。执行追踪器通常会收集过多的信息，在长期运行的生产服务中不太实用，而飞行记录器则像一个小小的时光机，允许服务在出现问题之后，以极高的细节快照最近发生的事件。</p>
<h2>安全软件开发</h2>
<p>Go 继续加强其对安全软件开发的承诺，在其<a href="https://tonybai.com/2024/10/19/go-crypto-package-design-deep-dive">原生加密包</a>方面取得了重大进展，并演进其标准库以增强安全性。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/paid/go-crypto-101-qr.png" alt="img{512x368}" /></p>
<p>Go 在标准库中附带了一整套原生加密包，这些包在过去一年中达到了两个重要的里程碑。由独立安全公司 <a href="https://www.trailofbits.com/">Trail of Bits</a> 进行的安全审计取得了<a href="https://tonybai.com/2025/05/21/go-crypto-audit">优异的结果</a>，仅有一个低严重性的发现。此外，通过 Go 安全团队与 <a href="https://geomys.org/">Geomys</a> 的合作，这些包获得了 CAVP 认证，为<a href="https://tonybai.com/2024/11/16/go-crypto-and-fips-140">完整的 FIPS 140-3 认证</a>铺平了道路。这对于在某些受监管环境中的 Go 用户来说是一项至关重要的进展。FIPS 140 合规性，以往由于需要使用不受支持的解决方案而成为一个摩擦点，现在将被无缝集成，解决了与安全性、开发者体验、功能性、发布速度和合规性相关的问题。</p>
<p>Go 标准库持续演进，以实现默认安全和设计安全。例如，Go 1.24 中添加的 <a href="https://pkg.go.dev/os#Root">os.Root</a> API 实现了<a href="https://go.dev/blog/osroot">抗遍历的文件系统访问</a>，有效地对抗了一类漏洞，即攻击者可能操纵程序访问本应不可访问的文件。这类漏洞在没有底层平台和操作系统支持的情况下极具挑战性，而新的 <a href="https://pkg.go.dev/os#Root">os.Root</a> API 提供了一个直接、一致且可移植的解决方案。</p>
<h2>底层改进</h2>
<p>除了用户可见的更改，Go 在过去一年中还在底层做了重大改进。</p>
<p>在 Go 1.24 中，我们完全<a href="https://tonybai.com/2024/11/14/go-map-use-swiss-table/">重新设计了 map 的实现</a>，借鉴了哈希表设计中最新、最伟大的思想。这一更改是完全透明的，并为 map 的性能带来了显著提升，降低了 map 操作的尾部延迟，在某些情况下甚至带来了显著的内存节省。</p>
<p>Go 1.25 包含了一个实验性的、在 Go 垃圾回收器方面的重大进步，名为 <a href="https://tonybai.com/2025/10/31/deep-into-go-green-tea-gc/">Green Tea</a>。Green Tea 在许多应用程序中将垃圾回收开销减少了至少 10%，有时甚至高达 40%。它使用了一种专为当今硬件的能力和限制而设计的新颖算法，并开辟了一个我们正热切探索的新设计空间。例如，在即将发布的 Go 1.26 版本中，Green Tea 将在<a href="https://tonybai.com/2025/08/22/go-simd-package-preview">支持 AVX-512 向量指令</a>的硬件上额外实现 10% 的垃圾回收器开销降低——这在旧算法中几乎是不可能的。Green Tea 将在 Go 1.26 中默认启用；用户只需升级他们的 Go 版本即可受益。</p>
<h2>进一步发展软件开发栈</h2>
<p>Go 远不止于语言和标准库。它是一个软件开发平台，在过去一年里，我们还对 <a href="https://go.dev/gopls">gopls 语言服务器</a>进行了四次常规发布，并建立了合作伙伴关系以支持新兴的智能体应用程序新框架。</p>
<p>Gopls 为 VS Code 和其他基于 LSP 的编辑器和 IDE 提供 Go 支持。每个版本都有一系列的功能和改进，提升了阅读和编写 Go 代码的体验（详情请见 <a href="https://go.dev/gopls/release/v0.17.0">v0.17.0</a>、<a href="https://go.dev/gopls/release/v0.18.0">v0.18.0</a>、<a href="https://go.dev/gopls/release/v0.19.0">v0.19.0</a> 和 <a href="https://go.dev/gopls/release/v0.20.0">v0.20.0</a> 的发布说明，或我们新的 <a href="https://go.dev/gopls/features">gopls 功能文档</a>！）。一些亮点包括：许多新增和增强的分析器，帮助开发者编写更地道和健壮的 Go 代码；对变量提取、变量内联和 JSON 结构体标签的重构支持；以及一个<a href="https://go.dev/gopls/features/mcp">实验性的内置MCP服务器</a>，用于模型上下文协议（MCP），它以 MCP 工具的形式向 AI 助手暴露了 gopls 的一部分功能。</p>
<p>从 gopls v0.18.0 开始，我们开始探索自动代码现代化工具。随着 Go 的演进，每个版本都带来了新的能力和新的惯用法；Go 程序员一直在寻找其他方法来做的事情，现在有了新的、更好的方法。Go 坚守其<a href="https://go.dev/doc/go1compat">兼容性承诺</a>——旧的方式将永远有效——但尽管如此，这在旧惯用法和新惯用法之间造成了分歧。现代化工具是静态分析工具，它们能识别旧的惯用法，并建议更快、更可读、更安全、更现代的替代方案，并且能一键可靠地完成。我们希望现代化工具能像 gofmt 为<a href="https://go.dev/blog/gofmt">风格一致性</a>所做的那样，为惯用法一致性做出贡献。我们将现代化工具集成为 IDE 的建议，在那里它们不仅能帮助开发者维护更一致的编码标准，我们相信它们还能帮助开发者发现新功能并跟上最新技术。我们相信现代化工具还能帮助 AI 编码助手跟上最新技术，并对抗它们倾向于强化关于 Go 语言、API 和惯用法的过时知识。即将到来的 Go 1.26 版本将包括<a href="https://tonybai.com/2025/07/28/go-fix-reborn">对长期休眠的 go fix 命令的全面改造</a>，使其能够批量应用全套的现代化工具，回归其<a href="https://go.dev/blog/introducing-gofix">Go 1.0 之前的根源</a>。</p>
<p>九月底，我们与 <a href="https://www.anthropic.com/">Anthropic</a> 和 Go 社区合作，发布了<a href="https://modelcontextprotocol.io/">模型上下文协议（MCP）</a>的<a href="https://tonybai.com/2025/07/10/mcp-official-go-sdk">官方 Go SDK</a> 的 <a href="https://github.com/modelcontextprotocol/go-sdk/releases/tag/v1.0.0">v1.0.0</a>。这个 SDK 支持 MCP 客户端和 MCP 服务器，并支撑着 gopls 中新的 MCP 功能。将这项工作开源，有助于赋能围绕 Go 构建的日益增长的开源智能体生态系统的其他领域，例如最近由 <a href="https://www.google.com/">Google</a> 发布的<a href="https://github.com/google/adk-go">Agent Development Kit (ADK) for Go</a>。ADK Go 建立在 Go MCP SDK 之上，为构建模块化的多智能体应用程序和系统提供了一个地道的框架。Go MCP SDK 和 ADK Go 展示了 Go 在并发、性能和可靠性方面的独特优势如何使 Go 在生产级 AI 开发中脱颖而出，我们预计未来几年会有更多的 AI 工作负载用 Go 编写。</p>
<h2>展望未来</h2>
<p>Go 前方是激动人心的一年。</p>
<p>我们正在通过全新的 go fix 命令、对 AI 编码助手的更深层次支持，以及对 gopls 和 VS Code Go 的持续改进，来提升开发者的生产力。Green Tea 垃圾回收器的正式可用、对<a href="https://tonybai.com/2025/06/09/go-simd-intrinsics/">单指令多数据（SIMD）硬件功能的原生支持</a>，以及运行时和标准库对编写能更好地扩展到大规模多核硬件代码的支持，将继续使 Go 与现代硬件保持一致，并提高生产效率。我们正专注于 Go 的“生产栈”库和诊断工具，包括由 Joe Tsai 和 Go 社区成员共同推动的、对 encoding/json 的一次大规模（且酝酿已久）的<a href="https://go.dev/issue/71497">升级</a>；由 <a href="https://www.uber.com/us/en/about/">Uber</a> 的编程系统团队贡献的<a href="https://tonybai.com/2025/07/24/deadlock-detection-by-gc/">泄露 goroutine 分析</a>；以及对 net/http、unicode 和其他基础包的许多其他改进。我们正致力于为使用 Go 和 AI 构建提供清晰的路径，谨慎地演进语言平台以适应当今开发者不断变化的需求，并构建能够同时帮助人类开发者和 AI 助手及系统的工具和能力。</p>
<p>在 Go 开源发布 16 周年之际，我们也在展望 Go 开源项目本身的未来。从其<a href="https://www.youtube.com/watch?v=wwoWei-GAPo">卑微的开端</a>开始，Go 已经形成了一个蓬勃发展的贡献者社区。为了继续最好地满足我们不断扩大的用户群的需求，尤其是在软件行业动荡的时期，我们正在研究如何更好地扩展 Go 的开发流程——同时不失 Go 的基本原则——并更深入地让我们的优秀贡献者社区参与进来。</p>
<p>没有我们卓越的用户和贡献者社区，Go 就不可能有今天的成就。我们祝愿大家在新的一年里一切顺利！</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>想系统学习Go，构建扎实的知识体系？</strong></p>
<p>我的新书《<a href="https://book.douban.com/subject/37499496/">Go语言第一课</a>》是你的首选。源自2.4万人好评的极客时间专栏，内容全面升级，同步至Go 1.24。首发期有专属五折优惠，不到40元即可入手，扫码即可拥有这本300页的Go语言入门宝典，即刻开启你的Go语言高效学习之旅！</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/go-primer-published-4.png" 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/11/15/go-turns-16/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>想用Go复刻“Claude Code”？那你得先补上TUI这一课</title>
		<link>https://tonybai.com/2025/08/08/go-tui-primer/</link>
		<comments>https://tonybai.com/2025/08/08/go-tui-primer/#comments</comments>
		<pubDate>Fri, 08 Aug 2025 01:35:19 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[Bubbles]]></category>
		<category><![CDATA[bubletea]]></category>
		<category><![CDATA[charm.sh]]></category>
		<category><![CDATA[ClaudeCode]]></category>
		<category><![CDATA[cmd]]></category>
		<category><![CDATA[Elm]]></category>
		<category><![CDATA[GeminiCli]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[k9s]]></category>
		<category><![CDATA[KeyMsg]]></category>
		<category><![CDATA[lazygit]]></category>
		<category><![CDATA[LipGloss]]></category>
		<category><![CDATA[model-view-update]]></category>
		<category><![CDATA[Msg]]></category>
		<category><![CDATA[TUI]]></category>
		<category><![CDATA[vscode]]></category>
		<category><![CDATA[键盘]]></category>
		<category><![CDATA[鼠标]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=5012</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/08/08/go-tui-primer 大家好，我是Tony Bai。 最近，AI 圈最火的莫过于Anthropic推出的“Claude Code”&#8211; 一款基于终端的编码智能体工具： 当你在终端窗口里，看着 AI 实时地帮你生成、修改、编译、测试和运行一个 Web 应用，并且能立刻看到输出和反馈时，那种感觉只能用“震撼”来形容。 作为一名 Go 开发者，我当时脑子里冒出的第一个念头就是： “如果我能用 Go，在自己的终端里，也实现一套这样的工作流，那该多酷？” 想象一下：你写一个 CLI 工具，它可以连接到任何一个大模型 API。你给它一个需求，比如“帮我写一个处理用户注册的 Go HTTP Handler”，然后： 你的终端左侧窗口，开始像打字机一样，流式输出 AI 生成的 Go 代码。 右侧窗口，实时显示出代码的编译状态、单元测试的进度条和结果。 当代码完成时，它自动运行起来，并告诉你：“服务已在 localhost:8080 启动，请测试。” 这个场景，就是我们开发者梦想中的“编码伙伴”，也是一个宏大但并非遥不可及的目标。 要实现这个目标，除了调用 AI 的 API，最关键、也是我们最容易忽视的一环是——如何构建这样一个复杂的、多窗口的、可实时交互的终端界面？ 答案，就是 TUI (Terminal User Interface) 开发。 你的下一个 Go 程序，值得拥有一张“脸” 我们很多 Go 开发者，都把技能点加在了后端性能、并发模型上，这当然没错。但我们常常忽略了程序的“脸面”——它的交互体验。 传统的 CLI 工具，就像一个只会用专业术语说话的机器人，强大但冷漠。而一个现代的 [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2025/go-tui-primer-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/08/08/go-tui-primer">本文永久链接</a> &#8211; https://tonybai.com/2025/08/08/go-tui-primer</p>
<p>大家好，我是Tony Bai。</p>
<p>最近，AI 圈最火的莫过于Anthropic推出的“Claude Code”&#8211; 一款基于终端的编码智能体工具：</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/go-tui-primer-2.png" alt="" /></p>
<p>当你在终端窗口里，看着 AI 实时地帮你生成、修改、编译、测试和运行一个 Web 应用，并且能立刻看到输出和反馈时，那种感觉只能用“震撼”来形容。</p>
<p>作为一名 Go 开发者，我当时脑子里冒出的第一个念头就是：</p>
<p><strong>“如果我能用 Go，在自己的终端里，也实现一套这样的工作流，那该多酷？”</strong></p>
<p>想象一下：你写一个 CLI 工具，它可以连接到任何一个大模型 API。你给它一个需求，比如“帮我写一个处理用户注册的 Go HTTP Handler”，然后：</p>
<ol>
<li>你的终端<strong>左侧窗口</strong>，开始像打字机一样，流式输出 AI 生成的 Go 代码。</li>
<li><strong>右侧窗口</strong>，实时显示出代码的编译状态、单元测试的进度条和结果。</li>
<li>当代码完成时，它自动运行起来，并告诉你：“服务已在 localhost:8080 启动，请测试。”</li>
</ol>
<p>这个场景，就是我们开发者梦想中的“编码伙伴”，也是一个宏大但并非遥不可及的目标。</p>
<p>要实现这个目标，除了调用 AI 的 API，最关键、也是我们最容易忽视的一环是——<strong>如何构建这样一个复杂的、多窗口的、可实时交互的终端界面？</strong></p>
<p>答案，就是 <strong>TUI (Terminal User Interface)</strong> 开发。</p>
<h2>你的下一个 Go 程序，值得拥有一张“脸”</h2>
<p>我们很多 Go 开发者，都把技能点加在了后端性能、并发模型上，这当然没错。但我们常常忽略了程序的“脸面”——它的交互体验。</p>
<p>传统的 CLI 工具，就像一个只会用专业术语说话的机器人，强大但冷漠。而一个现代的 TUI 应用，则像一个能与你沟通的智能助手。</p>
<p>它能在终端这个我们最熟悉、最高效的环境里，提供类似图形界面的直观体验：</p>
<ul>
<li><strong>多窗口布局：</strong> 像 VS Code 一样，清晰地划分代码区、状态区、输出区。</li>
<li><strong>实时反馈：</strong> 进度条、加载动画、状态指示器，让一切尽在掌握。</li>
<li><strong>交互式组件：</strong> 可滚动的列表、可输入的文本框、可选择的菜单，告别死记硬背。</li>
</ul>
<p>而 Go 语言，凭借其无与伦比的性能和静态编译能力，正是构建这类高性能 TUI 应用的最佳选择。</p>
<h2>但这条路，自学起来并不容易</h2>
<p>当你兴致勃勃地去 GitHub 搜索 Go TUI 库时，你可能会发现一些挑战：</p>
<ul>
<li><strong>陡峭的思维转变：</strong> 最流行的库 bubbletea，用的是一种函数式的 Elm 架构。它的 Model-View-Update 模式，对于习惯了传统命令式编程的 Gopher 来说，像是在学习一门“外语”。</li>
<li><strong>知识点零散：</strong> 如何处理异步任务？如何设计可复用的组件？如何美化 UI？这些问题的答案散落在各种英文文档和 GitHub Issue 里，很难形成体系。</li>
<li><strong>缺乏实战引导：</strong> 看完基础教程，能写个计数器，但一到真实项目就无从下手，不知道如何将简单的 Demo 组合成一个复杂的应用。</li>
</ul>
<p>为了帮你扫清这些障碍，让你能把精力聚焦在创造性的工作上，而不是在入门的坑里反复挣扎，我倾力打造了一门付费微专栏——《<a href="https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzIyNzM0MDk0Mg==&amp;action=getalbum&amp;album_id=4108702531688333316#wechat_redirect">重塑终端：Go TUI 开发入门课</a>》。</p>
<p>这门课，就是你通往“用 Go 复刻 Claude Code”梦想的第一块，也是最重要的一块基石。</p>
<h2>在这门课里，你将得到什么？</h2>
<p>本专栏专为有一定 Go 基础，但对 TUI 开发感到陌生或困惑的你而设计。无论你是想打造惊艳的开源工具，还是想给内部平台配一个更酷的客户端，你都能在这里找到清晰的路径。</p>
<p><strong>通过 5 讲精心设计的内容，你将：</strong></p>
<ul>
<li><strong>第 1 讲 | 新利器：</strong> 我们将重新认识 TUI，理解它为何在 AI 时代成为 Go 开发者的“新利器”，并为你建立一套坚实的理论认知框架。</li>
<li><strong>第 2 讲 | 核心架构：</strong> 彻底解密 bubbletea 背后的 Elm 架构。我将用最直观的方式，带你掌握 Model-View-Update 这一核心思想，这是编写可维护 TUI 应用的基石。</li>
<li><strong>第 3 讲 | 交互之魂：</strong> 深入 bubbletea 的消息（Msg）与命令（Cmd）系统。你将学会如何处理键盘、鼠标等各种输入，以及如何优雅地执行网络请求等异步任务而不阻塞界面。</li>
<li><strong>第 4 讲 | 终端美学：</strong> 学习使用 Charm 生态中的 Lip Gloss 和 Bubbles 库。我将教你如何为你的 TUI 应用添加漂亮的色彩、布局和边框，并快速集成输入框、列表、进度条等现成组件。</li>
<li><strong>第 5 讲 | 实战串讲：</strong> 我们将所有知识融会贯通，从零开始，手把手带你构建一个功能完备的“终端版 GitHub Issue 查看器(如下图)”。这个项目将成为你的代码库，为你未来的 TUI 开发提供一个绝佳的脚手架。</li>
</ul>
<p><img src="https://tonybai.com/wp-content/uploads/2025/go-tui-primer-3.png" alt="" /></p>
<p>完成这门课后，你将不仅仅是“会用”bubbletea，而是真正“理解”了现代 TUI 应用的构建哲学。你将有足够的能力和信心，去挑战那个“用 Go 复刻 Claude Code”的终极目标。</p>
<p><strong>梦想再宏大，也要从第一行代码开始。而一个好的课程，能让你的第一行代码，走在最正确的路上。</strong></p>
<p><strong>今天，<a href="https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzIyNzM0MDk0Mg==&amp;action=getalbum&amp;album_id=4108702531688333316#wechat_redirect">微专栏正式上线</a>！扫描下方二维码，立即订阅。让我们一起，用 Go 重塑终端，开启属于你的 AI + TUI 开发之旅！</strong></p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/paid/go-tui-primer-pr.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>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求，请扫描下方公众号二维码，与我私信联系。</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/08/go-tui-primer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>你的命令行，即将迎来一场“AI 革命”</title>
		<link>https://tonybai.com/2025/07/09/gemini-cli-starting-guide/</link>
		<comments>https://tonybai.com/2025/07/09/gemini-cli-starting-guide/#comments</comments>
		<pubDate>Wed, 09 Jul 2025 00:23:57 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[Agent]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[ChatGPT]]></category>
		<category><![CDATA[ClaudeCode]]></category>
		<category><![CDATA[Codex]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[Emacs]]></category>
		<category><![CDATA[gemini-cli]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[JetBrains]]></category>
		<category><![CDATA[MCP]]></category>
		<category><![CDATA[openai]]></category>
		<category><![CDATA[Vim]]></category>
		<category><![CDATA[vscode]]></category>
		<category><![CDATA[代理]]></category>
		<category><![CDATA[工具]]></category>
		<category><![CDATA[智能体]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=4887</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/07/09/gemini-cli-starting-guide 大家好，我是Tony Bai。 在软件开发的历史长河中，我们与机器的交互界面经历了一场有趣的轮回。 曾几何时，发光的绿色字符在黑色屏幕上跳动，命令行是我们掌控一切的神圣权杖。从编辑器（Vim/Emacs）到编译器，再到版本控制，整个世界都安然地存在于终端的心跳之中。 随后，图形用户界面（GUI）带来了集成开发环境（IDE）的黄金时代。Borland、Visual Studio、Eclipse、JetBrains&#8230; 我们将一切都“集成”到了一个窗口里，享受着点击、拖拽和可视化调试带来的便利。命令行似乎一度退居次席，成了执行零散脚本的“后台工具”。 而今天，当我们以为 VS Code 这样轻快、插件丰富的编辑器已经统一江湖时，一股强劲的“复古之风”正悄然刮起。但这一次，它并非简单的怀旧，而是一场由 AI 驱动的、向命令行的“伟大回归”。 为什么是现在？ 因为 AI 的出现，再次打破了 IDE 创造的“完美闭环”。我们发现自己又一次陷入了新的“工作流摩擦”：我们的代码在一个窗口，而我们的 AI “外脑”（ChatGPT/Gemini Web）在另一个窗口。我们成了上下文的搬运工，在复制粘贴中消耗着宝贵的专注力。 IDE 插件虽有所缓解，但它们更像是被“关在笼子里”的 AI，能力受限于 IDE 提供的 API。它们无法真正理解你的整个系统环境，无法为你执行一条 docker build 命令，更无法调用你私有的测试脚本。 我们需要的，不仅仅是一个会写代码的 AI。我们需要一个能理解我们整个工作流，并能动手执行的 AI。敏锐的开发者和 AI 公司都已意识到，下一个效率的爆发点，不在 GUI，而在那片最经典、最高效的战场——命令行。 这，正是这场“命令行革命”的核心。 于是，一个全新的物种 “命令行AI智能体 (Command-Line AI Agent)” 开始涌现。OpenAI Codex、Claude Code等拥有强大能力的商业公司背书的各类智能体脚本便像雨后春笋般出现。而在这一新兴的赛道上，Google也携其 Gemini CLI，给出了一个与众不同的答案。它更侧重于工作流自动化 (Workflow Automation)。更具吸引力的是，通过个人 Google 账户认证，你就能享受到慷慨的免费使用额度，这极大地降低了每一位开发者体验这场命令行革命的门槛。 [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2025/gemini-cli-starting-guide-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/07/09/gemini-cli-starting-guide">本文永久链接</a> &#8211; https://tonybai.com/2025/07/09/gemini-cli-starting-guide</p>
<p>大家好，我是Tony Bai。</p>
<p>在软件开发的历史长河中，我们与机器的交互界面经历了一场有趣的轮回。</p>
<p>曾几何时，发光的绿色字符在黑色屏幕上跳动，命令行是我们掌控一切的神圣权杖。从编辑器（Vim/Emacs）到编译器，再到版本控制，整个世界都安然地存在于终端的心跳之中。</p>
<p>随后，图形用户界面（GUI）带来了集成开发环境（IDE）的黄金时代。Borland、Visual Studio、Eclipse、JetBrains&#8230; 我们将一切都“集成”到了一个窗口里，享受着点击、拖拽和可视化调试带来的便利。命令行似乎一度退居次席，成了执行零散脚本的“后台工具”。</p>
<p>而今天，当我们以为 VS Code 这样轻快、插件丰富的编辑器已经统一江湖时，一股强劲的“复古之风”正悄然刮起。但这一次，它并非简单的怀旧，而是一场由 <strong>AI 驱动的、向命令行的“伟大回归”</strong>。</p>
<p><strong>为什么是现在？</strong></p>
<p>因为 AI 的出现，再次打破了 IDE 创造的“完美闭环”。我们发现自己又一次陷入了新的“工作流摩擦”：我们的代码在一个窗口，而我们的 AI “外脑”（ChatGPT/Gemini Web）在另一个窗口。我们成了上下文的搬运工，在复制粘贴中消耗着宝贵的专注力。</p>
<p>IDE 插件虽有所缓解，但它们更像是被“关在笼子里”的 AI，能力受限于 IDE 提供的 API。它们无法真正理解你的整个系统环境，无法为你执行一条 docker build 命令，更无法调用你私有的测试脚本。</p>
<p>我们需要的，不仅仅是一个会写代码的 AI。我们需要一个能<strong>理解我们整个工作流</strong>，并能<strong>动手执行</strong>的 AI。敏锐的开发者和 AI 公司都已意识到，下一个效率的爆发点，不在 GUI，而在那片最经典、最高效的战场——命令行。</p>
<p>这，正是这场“命令行革命”的核心。</p>
<p>于是，一个全新的物种 “命令行AI智能体 (Command-Line AI Agent)” 开始涌现。OpenAI Codex、Claude Code等拥有强大能力的商业公司背书的各类智能体脚本便像雨后春笋般出现。而在这一新兴的赛道上，Google也携其 Gemini CLI，给出了一个与众不同的答案。它更侧重于工作流自动化 (Workflow Automation)。更具吸引力的是，通过个人 Google 账户认证，你就能享受到慷慨的免费使用额度，这极大地降低了每一位开发者体验这场命令行革命的门槛。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/paid/gemini-cli-starting-guide-01-3.png" alt="" /></p>
<p>正是因为 Gemini CLI 的这种“慷慨”，我认为它值得一次系统而深入的探索。</p>
<p>我即将开启一个全新的微专栏系列 <strong>《Gemini CLI：重新定义命令行 AI 开发》</strong>，该专栏将用 <strong>5篇由浅入深的实战文章</strong>，向你完整地展示，当今最前沿的大语言模型(比如Gemini 2.5 pro)，是如何与开发世界最经典、最高效的交互界面——命令行——相结合，从而迸发出惊人的能量。此外，专栏中的示例均采用Go代码。</p>
<p>在这个系列中，你将看到：</p>
<ul>
<li>
<p><strong>第一篇《入门篇》：</strong> 我们将为你带来初见的“Wow 时刻”。你将看到 Gemini CLI 如何仅用一个 @ 符号，就读懂并分析一个你完全陌生的 Go 项目，这是一种你从未体验过的、AI 与本地文件系统的深度融合。</p>
</li>
<li>
<p><strong>第二篇《实战篇》：</strong> 我们将带你彻底驾驭 @、!、/ 这三驾马车，在真实的 Go 项目中，完成从代码分析、编译测试到 Git 操作的全流程。我们将让你相信，大部分开发任务，都可以且应该在命令行中一气呵成。</p>
</li>
<li>
<p><strong>第三篇《进阶篇》：</strong> 我们将为你系上 AI 时代的“安全带”。你将掌握 <strong>Checkpointing (快照回滚)</strong> 机制，让你可以像玩游戏读档一样，随时回退 AI 的任何一次代码修改，从而安心地让它进行最大胆的重构实验。</p>
</li>
<li>
<p><strong>第四篇《扩展篇》：</strong> 我们将带你扮演“造物主”的角色。你将学会如何通过<strong>自定义工具</strong>和 <strong>MCP 服务器</strong>，将你自己的脚本、公司的内部 API，甚至任何你能想到的外部系统，全部接入 Gemini CLI 的能力版图，打造真正属于你的神器。</p>
</li>
<li>
<p><strong>第五篇《应用篇》：</strong> 我们将展示一个终极工作流。如何用<strong>一句自然语言指令</strong>，驱动 AI 自动完成<strong>在线研究、信息整合、内容创作，并最终将一篇完整的 Markdown 技术报告保存在你的本地</strong>。这，是自动化思想的极致体现。</p>
</li>
</ul>
<p>这不关乎怀旧，这关乎进化。</p>
<p>这不是退回终端，而是带着 AI 的力量，重返我们最熟悉的战场。</p>
<p>如果你对提升开发效率有极致的追求，如果你相信最好的工具就应该在弹指之间，那么，请锁定我们。</p>
<p><strong>点击下方卡片，即刻关注，与我们一同见证这场正在发生的革命！</strong></p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/paid/gemini-cli-starting-guide-qr.png" alt="" /></p>
<hr />
<p>如果你和我们一样，对探索 Go 与 AI 的前沿交叉领域充满热情，那么这个微专栏仅仅是一个开始。</p>
<p>为了感谢核心读者的支持，并打造一个更具深度和互动性的交流平台，我决定：</p>
<p><strong>本付费微专栏的全部 5 篇文章，将在我的知识星球「Go &amp; AI 精进营」中同步免费发布！</strong></p>
<p><strong>扫描下方二维码，加入「Go &amp; AI 精进营」，与我们一起，站在未来看现在。</strong></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; 2025, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2025/07/09/gemini-cli-starting-guide/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>爽就完了！Go语言的“简单之美”为何让开发者直呼过瘾？</title>
		<link>https://tonybai.com/2025/06/12/grog-brain-heaven/</link>
		<comments>https://tonybai.com/2025/06/12/grog-brain-heaven/#comments</comments>
		<pubDate>Thu, 12 Jun 2025 01:00:22 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[defer]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[gobuild]]></category>
		<category><![CDATA[gofmt]]></category>
		<category><![CDATA[goland]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[gomodule]]></category>
		<category><![CDATA[goroutine]]></category>
		<category><![CDATA[gotest]]></category>
		<category><![CDATA[govet]]></category>
		<category><![CDATA[grop-brain]]></category>
		<category><![CDATA[reddit]]></category>
		<category><![CDATA[Scala]]></category>
		<category><![CDATA[stdlib]]></category>
		<category><![CDATA[toolchain]]></category>
		<category><![CDATA[Vim]]></category>
		<category><![CDATA[vscode]]></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=4813</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/06/12/grog-brain-heaven 大家好，我是Tony Bai。 最近，在国外的技术论坛 Reddit 的 Go 语言版块上，一个标题为“Go is so much fun, Grog brain heaven”的帖子，引爆了 Gopher 们的讨论热情。发帖的开发者用一种非常接地气的“原始人 (Grog)”口吻，激情赞扬了 Go 语言，核心就一个字——“爽！” 他列举了一堆理由：关键词少、特殊字符少、概念少、编译器快、工具链好用、标准库给力、没有复杂的构建系统……总而言之，Go 语言对于那些厌倦了复杂性、只想专注于“造东西”的开发者来说，简直就是“天堂”。 这个帖子迅速获得了大量 Go 开发者的强烈共鸣。一位从 Scala 转到 Go 的开发者形容这种体验像是“从100倍重力训练环境出来，到了只有1倍重力的地方，认知负荷大大降低。在Go里你就是直接做事，没有魔法，没有废话，简单直接。” 另一位开发者则惊叹于 Go 工具链的便捷：“只需安装 SDK 就完事了！” 更有甚者直言，Go 的杀手级特性恰恰在于其“缺乏特性 (lack of features)”。 这些发自肺腑的“声音”，不禁让我们深思：在这个技术日新月异、语言特性层出不穷的时代，为什么 Go 语言这种看似“朴素”的“简单”，反而能让如此多的开发者直呼过瘾，成为他们心中“YYDS”？ 在这篇文章中，我们就挑出原贴中几个典型的声音，一起来解读一下。 “Grog脑天堂”的呼唤：返璞归真，大道至简 原帖中提到的“Grog brain heaven”，我们可以理解为一种开发者对纯粹、直接、易于理解和掌控的技术的向往。尤其是在经历了那些充满“魔法”、特性繁杂、需要“JVM柔术”才能驾驭的复杂系统和语言的“洗礼”之后，Go 的出现就像一股清流，让人神清气爽。 “Grog” （可以想象成一个崇尚简单直接的原始人）喜欢造东西，不喜欢猜谜。Go 语言恰好满足了“Grog”的核心诉求： 学得快，忘得慢： 关键词少、特殊字符少、概念少。这意味着学习曲线平缓，上手极快，心智负担极低。你不需要记住成百上千的语法糖或复杂的元编程技巧。 [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2025/grog-brain-heaven-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/06/12/grog-brain-heaven">本文永久链接</a> &#8211; https://tonybai.com/2025/06/12/grog-brain-heaven</p>
<p>大家好，我是Tony Bai。</p>
<p>最近，在国外的技术论坛 Reddit 的 Go 语言版块上，一个标题为“<a href="https://www.reddit.com/r/golang/comments/1l8dxr7/go_is_so_much_fun_grog_brain_heaven/">Go is so much fun, Grog brain heaven</a>”的帖子，引爆了 Gopher 们的讨论热情。发帖的开发者用一种非常接地气的“原始人 (Grog)”口吻，激情赞扬了 Go 语言，核心就一个字——<strong>“爽！”</strong> 他列举了一堆理由：关键词少、特殊字符少、概念少、编译器快、工具链好用、标准库给力、没有复杂的构建系统……总而言之，Go 语言对于那些厌倦了复杂性、只想专注于“造东西”的开发者来说，简直就是“天堂”。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/grog-brain-heaven-2.png" alt="" /></p>
<p>这个帖子迅速获得了大量 Go 开发者的强烈共鸣。一位从 Scala 转到 Go 的开发者形容这种体验像是“从100倍重力训练环境出来，到了只有1倍重力的地方，认知负荷大大降低。在Go里你就是直接做事，没有魔法，没有废话，简单直接。” 另一位开发者则惊叹于 Go 工具链的便捷：“只需安装 SDK 就完事了！” 更有甚者直言，Go 的杀手级特性恰恰在于其“缺乏特性 (lack of features)”。</p>
<p>这些发自肺腑的“声音”，不禁让我们深思：在这个技术日新月异、语言特性层出不穷的时代，<strong>为什么 Go 语言这种看似“朴素”的“简单”，反而能让如此多的开发者直呼过瘾，成为他们心中“YYDS”？</strong> 在这篇文章中，我们就挑出原贴中几个典型的声音，一起来解读一下。</p>
<p><img src="https://tonybai.com/wp-content/uploads/course-card/iamtonybai-banner-2.gif" alt="" /></p>
<h2>“Grog脑天堂”的呼唤：返璞归真，大道至简</h2>
<p>原帖中提到的“Grog brain heaven”，我们可以理解为一种开发者对纯粹、直接、易于理解和掌控的技术的向往。尤其是在经历了那些充满“魔法”、特性繁杂、需要“JVM柔术”才能驾驭的复杂系统和语言的“洗礼”之后，Go 的出现就像一股清流，让人神清气爽。</p>
<p>“Grog” （可以想象成一个崇尚简单直接的原始人）喜欢造东西，不喜欢猜谜。Go 语言恰好满足了“Grog”的核心诉求：</p>
<ul>
<li><strong>学得快，忘得慢：</strong> 关键词少、特殊字符少、概念少。这意味着学习曲线平缓，上手极快，心智负担极低。你不需要记住成百上千的语法糖或复杂的元编程技巧。</li>
<li><strong>写得顺，读得懂：</strong> 直观的类 C 风格编程，对于有其他主流语言背景的开发者来说非常友好。代码通常自上而下、顺序执行，没有复杂的隐式行为或“魔法”般的控制跳转，使得理解和调试代码变得简单直接。</li>
<li><strong>用得爽，不出错：</strong>
<ul>
<li>defer 语句以其简洁实用的方式解决了资源释放等常见问题，写起来顺手，读起来明白。</li>
<li>error 作为普通值返回，让错误处理变得明确和可控，告别了try-catch嵌套和异常满天飞的噩梦。</li>
<li>多返回值和”inline declaration and definition”等特性，进一步提升了编码的流畅性和代码的可读性。</li>
</ul>
</li>
</ul>
<blockquote>
<p>注：发帖者所说的 “inline declaration and definition” 大概率是指向 Go 语言的短变量声明 :=。 这个特性极大地提升了 Go 代码的简洁性和编写效率，减少了冗余的类型声明，让开发者可以更专注于逻辑本身。当然，构体、切片、map的字面量初始化，以及匿名函数的即时定义也都体现了声明、定义、初始化等操作可以“一气呵成”的特点，也符合“inline declaration and definition”的直观感受。</p>
</blockquote>
<h2>“少即是多”：Go 语言设计哲学的胜利</h2>
<p>Go 语言的“简单”并非功能的缺失或设计的草率，而是<strong>一种经过深思熟虑的、以解决实际工程问题为导向的选择</strong>。它是 Go 语言“少即是多”设计哲学的具体体现，是有意为之的克制，是对不必要复杂性的摒弃。</p>
<p>正如一位 Go 开发者在评论中所言：<strong>“它的杀手级特性在于其缺乏特性。”</strong> Go 有意避免了许多在其他语言中常见的复杂特性，如传统的类继承、操作符重载、复杂的泛型系统（早期）、宏、隐式类型转换等。这种克制，使得 Go 代码更易于阅读、理解和维护，尤其是在大型团队协作中，大大降低了沟通成本和因误解特性而引入错误的风险。</p>
<h2>从“百倍重力”到“一倍重力”：迁移者的幸福感源泉</h2>
<p>那位从 Scala 转到 Go 的开发者所描述的“从100倍重力训练环境出来，到了只有1倍重力的地方”那种“如释重负”的感觉，道出了许多从复杂语言或生态迁移到 Go 的开发者的心声。他们厌倦了：</p>
<ul>
<li><strong>“魔法”背后的不可预测性：</strong> 一些语言的高级特性或框架虽然能在特定场景下提供便利，但也可能隐藏了复杂的实现细节，使得程序的行为难以预测，调试如同“探案”。</li>
<li><strong>“体操”般的性能调优和依赖管理：</strong> 正如他所抱怨的：“浪费时间搞依赖管理，做 JVM 调优以榨取性能根本不值得。”</li>
<li><strong>冗长的学习曲线和高昂的心智维护成本。</strong></li>
</ul>
<p>Go 的出现，让他们卸下了这些沉重的“认知负荷”。他们不再需要花费大量精力去理解语言本身的复杂性或与庞大而笨重的生态系统搏斗，而是可以将精力聚焦在业务逻辑和解决实际问题上。这种“解放感”，是 Go 赋予迁移者的最直接的幸福感。</p>
<h2>工具链的“无痛体验”：“它就是好用！”</h2>
<p>除了语言本身的简洁，Go 语言<strong>开箱即用、体验极佳的工具链</strong>也是其备受赞誉的核心原因之一，是开发者“爽感”的重要来源。</p>
<p>原帖作者特别提到：“工具就是好用（尤其是在 Nvim 里）”。评论区的另一位开发者也表示：“Go 的工具链是我最喜欢的部分，我从不与之‘顶牛’。” 还有开发者在对比了过去维护复杂构建镜像（如 dockcross toolchain）的痛苦经历后，对 Go 工具链的优秀感到“疯狂”。</p>
<p>这种“不顶牛”、“不折腾”的工具链体验，体现在：</p>
<ul>
<li><strong>极快的编译速度：</strong> 使得开发迭代和反馈循环非常迅速。</li>
<li><strong>统一且无需配置的构建系统 (go build)：</strong> 告别了 Makefile、Maven、Gradle、Webpack 等复杂构建工具的学习和配置成本。</li>
<li><strong>内置的代码格式化 (gofmt) 和静态检查 (go vet)：</strong> 保证了团队代码风格的一致性和早期问题的发现。</li>
<li><strong>简洁高效的包管理 (go mod)：</strong> 解决了早期 Go 版本在依赖管理上的痛点，提供了清晰、可靠的依赖管理方案。</li>
<li><strong>强大的语言服务器协议 (LSP) 支持 (gopls)：</strong> 为各种编辑器（如 VS Code, Neovim, Goland）提供了流畅、智能的编码辅助体验。</li>
<li><strong>简单直接的测试框架 (go test)：</strong> 内置支持单元测试、基准测试、示例测试，易于上手和集成。</li>
</ul>
<p>正是这些设计精良、高度整合的工具，让 Go 开发者能够拥有一个“丝滑”的开发体验，将精力从繁琐的工具配置和环境问题中解放出来。</p>
<h2>Go 的务实主义与工程效率：为解决问题而生</h2>
<p>Go 语言从诞生之初，就带有强烈的<strong>务实主义和工程导向</strong>。它的设计目标之一，就是为了提高大型软件项目（尤其是在 Google 内部）的开发效率和可维护性。</p>
<ul>
<li><strong>极其丰富的标准库：</strong> 正如发帖者所言的“shit ton of stdlib”（极其丰富的标准库），Go 强大的标准库覆盖了网络编程、并发处理、数据编解码、加密、I/O 操作等众多领域，极大地减少了对外部第三方库的依赖，降低了项目的复杂性和潜在的供应链风险。</li>
<li><strong>原生可执行文件，简化部署：</strong> Go 程序通常被编译成单个静态链接的可执行文件，不依赖外部运行时（如 JVM、Python解释器等），使得部署过程极其简单，非常契合现代云原生和容器化部署的趋势。</li>
</ul>
<p>这些特性共同构成了 Go 在工程实践中的核心竞争力，使其成为构建网络服务、微服务、CLI 工具、基础设施软件等领域的理想选择。</p>
<h2>小结：简单不是简陋，而是深思熟虑的强大</h2>
<p>回到最初的问题：为什么 Go 语言的“简单之美”能让开发者直呼过瘾？</p>
<p>因为这种“简单”并非功能的缺失或设计的草率，而是<strong>一种深思熟虑的选择，一种对复杂性的克制，一种对开发者体验的极致追求。</strong> 它将“简单留给用户，将复杂留给自己（语言和工具链的设计者）”的理念贯彻到底。</p>
<p>Go 的魅力，在于它剔除了不必要的枝蔓，回归到编程的本质——清晰地表达逻辑，高效地解决问题。它让开发者能够以一种更接近直觉的方式去构建事物，而无需在抽象的迷宫中苦苦挣扎。</p>
<p>在这个日益复杂的世界里，Go 语言提供的这种“简单”和“直接”，本身就是一种强大的力量。它让我们能够更快地将想法付诸实践，更专注于创造价值，并在这个过程中享受到纯粹的构建乐趣。</p>
<p>这或许就是为什么，越来越多的开发者，在体验过 Go 语言带来的畅快之后，会由衷地感叹一句：“爽就完了！”</p>
<hr />
<p><strong>聊一聊，也帮个忙：</strong></p>
<ul>
<li><strong>你最喜欢 Go 语言的哪个“简单”特性？它在你的工作中带来了哪些便利和“爽”点？</strong></li>
<li><strong>你是否也有过从其他“复杂”语言或技术栈迁移到 Go 后，感到“如释重负”、“直呼过瘾”的经历？</strong></li>
<li><strong>除了文中提到的，你认为 Go 语言还有哪些让人“一旦上手，爱不释手”的魅力？</strong></li>
</ul>
<p>欢迎在<strong>评论区</strong>留下你的经验、思考和“爽点”！如果你觉得这篇文章道出了你对 Go 的喜爱，也请<strong>转发给你身边的 Gopher 朋友们</strong>，让更多人了解 Go 的“简单之美”！</p>
<p><strong>想与我进行更深入的 Go 语言设计哲学、工程实践与 AI 技术交流吗？</strong> 欢迎加入我的<strong>“Go &amp; AI 精进营”知识星球</strong>。</p>
<p><img src="http://image.tonybai.com/img/tonybai/gopher-and-ai-tribe-zsxq-small-card.jpg" alt="img{512x368}" /></p>
<p>我们星球见！</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/12/grog-brain-heaven/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>“Rustacean”胚胎 vs “Gopher”胚胎：假如用技术栈测“人格”，你会是哪一款？</title>
		<link>https://tonybai.com/2025/06/07/nucleus-embryo/</link>
		<comments>https://tonybai.com/2025/06/07/nucleus-embryo/#comments</comments>
		<pubDate>Sat, 07 Jun 2025 12:08:56 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[ArchLinux]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[goroutine]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[JetBrains]]></category>
		<category><![CDATA[macos]]></category>
		<category><![CDATA[NeoVim]]></category>
		<category><![CDATA[OS]]></category>
		<category><![CDATA[Rust]]></category>
		<category><![CDATA[Rustacean]]></category>
		<category><![CDATA[Vim]]></category>
		<category><![CDATA[vscode]]></category>
		<category><![CDATA[并发]]></category>
		<category><![CDATA[接口]]></category>
		<category><![CDATA[测试]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=4799</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/06/07/nucleus-embryo 大家好，我是Tony Bai。 最近，一张名为 “Nucleus Embryo” 的神秘图片在开发者圈子里悄然流传，引发了大家会心一笑（可能还带有一丝“我懂的”的复杂表情）。这张图煞有介事地对比了两个假想的“胚胎”——Embryo 1 和 Embryo 2——据称它们在“出厂设置”时，就已预装了不同的“技术基因”。 乍一看，这图表做得还挺像那么回事：有“Autism (自闭症倾向)”、“ADHD (多动症倾向)”、“Gender Dysphoria (性别焦虑倾向)”这些不明觉厉的百分点，还有看似严谨的“IQ (智商)”点数。但定睛一瞧，嘿，这“Language (编程语言)”、“Editor (编辑器)”、“OS (操作系统)”一栏，赫然出现了我们熟悉的 Rust、Go、VS Code (或类似现代IDE)、Neovim (或Vim)、Arch Linux 和 macOS 的 Logo！ 这显然是一张充满网络 Meme 精神的“恶搞图”，将复杂的人类特征与纯粹的技术偏好进行了一番天马行空的“强行配对”。 今天，我们就本着“纯属娱乐，请勿当真”的精神，来趣味解读一下，假如用技术栈来“测人格”，这两个“胚胎”分别代表了哪一款开发者“出厂画像”？而你，又更接近哪一款呢？ (郑重声明：以下解读纯属借助AI进行的基于网络 Meme 的趣味联想和对技术社区刻板印象的调侃，不代表任何科学观点，更不涉及对任何人群的评价或歧视。请大家在这个闲暇周末轻松阅读，切勿对号入座或上纲上线！) Embryo 1 号：“硬核掌控者”画像？ 让我们来看看 Embryo 1 号的“技术基因配置”： Language: Rust Editor: VS Code (或其抽象变体/同类现代IDE) OS: Arch Linux 如果非要给这个配置画个像，它可能散发着一股浓浓的“硬核玩家”和“掌控一切”的气息： [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2025/nucleus-embryo-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/06/07/nucleus-embryo">本文永久链接</a> &#8211; https://tonybai.com/2025/06/07/nucleus-embryo</p>
<p>大家好，我是Tony Bai。</p>
<p>最近，一张名为 “Nucleus Embryo” 的神秘图片在开发者圈子里悄然流传，引发了大家会心一笑（可能还带有一丝“我懂的”的复杂表情）。这张图煞有介事地对比了两个假想的“胚胎”——Embryo 1 和 Embryo 2——据称它们在“出厂设置”时，就已预装了不同的“技术基因”。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/nucleus-embryo-2.jpg" alt="" /></p>
<p>乍一看，这图表做得还挺像那么回事：有“Autism (自闭症倾向)”、“ADHD (多动症倾向)”、“Gender Dysphoria (性别焦虑倾向)”这些不明觉厉的百分点，还有看似严谨的“IQ (智商)”点数。但定睛一瞧，嘿，这“Language (编程语言)”、“Editor (编辑器)”、“OS (操作系统)”一栏，赫然出现了我们熟悉的 Rust、Go、VS Code (或类似现代IDE)、Neovim (或Vim)、Arch Linux 和 macOS 的 Logo！</p>
<p><strong>这显然是一张充满网络 Meme 精神的“恶搞图”，将复杂的人类特征与纯粹的技术偏好进行了一番天马行空的“强行配对”。</strong> 今天，我们就本着“纯属娱乐，请勿当真”的精神，来趣味解读一下，假如用技术栈来“测人格”，这两个“胚胎”分别代表了哪一款开发者“出厂画像”？而你，又更接近哪一款呢？</p>
<p><strong>(郑重声明：以下解读纯属借助AI进行的基于网络 Meme 的趣味联想和对技术社区刻板印象的调侃，不代表任何科学观点，更不涉及对任何人群的评价或歧视。请大家在这个闲暇周末轻松阅读，切勿对号入座或上纲上线！)</strong></p>
<h2>Embryo 1 号：“硬核掌控者”画像？</h2>
<p>让我们来看看 Embryo 1 号的“技术基因配置”：</p>
<ul>
<li><strong>Language: Rust</strong></li>
<li><strong>Editor: VS Code (或其抽象变体/同类现代IDE)</strong></li>
<li><strong>OS: Arch Linux</strong></li>
</ul>
<p>如果非要给这个配置画个像，它可能散发着一股浓浓的“硬核玩家”和“掌控一切”的气息：</p>
<ul>
<li><strong>Rust 语言：</strong> 以其对内存安全、并发性能的极致追求和陡峭的学习曲线著称。选择 Rust 的开发者，往往被认为是对系统底层有深入理解、不畏惧复杂性、追求代码极致性能和安全性的“屠龙勇士”。他们可能热衷于讨论生命周期、所有权、借用检查，并以编写出“零成本抽象”的代码为荣。</li>
<li><strong>VS Code (或类似现代IDE)：</strong> 虽然图中 Logo 比较抽象，但整体风格偏向现代、功能丰富的集成开发环境。这表明 Embryo 1 号在追求硬核的同时，也懂得利用现代工具提升开发体验，追求效率与功能的平衡。</li>
<li><strong>Arch Linux：</strong> 一个以“Keep It Simple, Stupid” (KISS) 和用户中心为理念，但需要用户从头构建和配置的 Linux 发行版。选择 Arch Linux 的用户，通常被认为是喜欢完全掌控自己的操作系统、不介意“折腾”、动手能力极强的 Linux 极客。</li>
</ul>
<p><strong>趣味解读 Embryo 1 号“人格”标签（纯属虚构，仅供娱乐）：</strong></p>
<ul>
<li><strong>优点：</strong> 追求极致、严谨细致、底层功力深厚、动手能力强、乐于探索。</li>
<li><strong>“萌点”/“槽点”：</strong> 可能会对“不够安全”、“不够高效”的代码嗤之鼻用鼻孔；热衷于向你安利 Arch Linux 并告诉你“编译大法好”；电脑上可能有无数个自己编译的工具链。</li>
<li><strong>口头禅（猜想）：</strong> “你的代码 unsafe 了吗？”、“这不符合 Rustacean 的精神！”、“Manjaro发行版？那是给新手玩的！”</li>
</ul>
<h2>Embryo 2 号：“务实效率派”画像？</h2>
<p>接下来，我们看看 Embryo 2 号的“出厂配置”：</p>
<ul>
<li><strong>Language: Go</strong></li>
<li><strong>Editor: Neovim (或 Vim)</strong></li>
<li><strong>OS: macOS</strong></li>
</ul>
<p>这个配置组合，则可能描绘出一位更注重简洁、实用和开发效率的“务实派”开发者：</p>
<ul>
<li><strong>Go 语言：</strong> 以其简洁的语法、高效的编译速度、强大的并发模型和完善的工具链闻名。选择 Go 的开发者，通常被认为是务实的工程派，他们更关注如何快速、可靠地构建可维护的系统，尤其在云原生、微服务、分布式系统领域得心应手。</li>
<li><strong>Neovim (或 Vim)：</strong> 一款高度可定制、键盘驱动、以高效文本编辑著称的编辑器。选择 Neovim/Vim 的开发者，往往追求极致的编辑效率和个性化的工作流，他们可能对鼠标“不屑一顾”，并能熟练地运用各种快捷键和插件组合。</li>
<li><strong>macOS：</strong> 一个以用户体验、设计美感和 Unix 友好性著称的操作系统。选择 macOS 的 Gopher，可能既看重其稳定易用的图形界面，也喜欢其背后强大的 Unix 内核和开发工具生态。</li>
</ul>
<p><strong>趣味解读 Embryo 2 号“人格”标签（纯属虚构，仅供娱乐）：</strong></p>
<ul>
<li><strong>优点：</strong> 简洁高效、务实专注、工程能力强、注重工具链整合。</li>
<li><strong>“萌点”/“槽点”：</strong> 可能会对“过度设计”、“不必要的复杂性”表示不解；坚信“少即是多，接口就是力量”；熟练掌握各种 hjkl 操作，并试图在一切应用中寻找 Vim 模式。</li>
<li><strong>口头禅（猜想）：</strong> “一个 goroutine 搞定！”、“这个接口设计不 Go！”、“JetBrains IDE？太重了，我用 Neovim/Vim 就够了！”</li>
</ul>
<p><img src="https://tonybai.com/wp-content/uploads/course-card/iamtonybai-banner-2.gif" alt="" /></p>
<h2>敏感标签的“荒谬”与 IQ 的“一视同仁”</h2>
<p>当然，这张图中除了技术栈，还有一些关于 Autism、ADHD、Gender Dysphoria 的“百分点”和 IQ 的“点数”。<strong>我们必须再次强调，将这些复杂且严肃的个体特征与技术选择简单粗暴地关联起来，是极度荒谬和不负责任的。</strong> 每个人的生理和心理状况都是独特的，不应被任何标签所定义，更不应与他们使用的工具挂钩。</p>
<p>有趣的是，在这张充满“偏见”的图中，两个“胚胎”的 IQ 点数却是相同的（都是+4）。这或许是制图者在用一种黑色幽默的方式暗示：<strong>无论你选择哪种技术栈，你的基础智力水平可能都差不多；或者，技术偏好与所谓的“智商高低”并无直接关联。</strong> 这点倒是值得我们深思。</p>
<h2>技术的本质是工具，标签仅供一笑</h2>
<p>说到底，这张 “Nucleus Embryo” 图，更像是一面映照技术社区中各种“梗”和“刻板印象”的哈哈镜。它用一种夸张的方式，触碰了我们潜意识中对不同技术群体的一些模糊认知。</p>
<p>编程语言、编辑器、操作系统，本质上都只是工具。选择使用哪种工具，更多的是基于个人偏好、项目需求、团队协作以及特定场景下的效率考量。<strong>没有任何一种技术栈组合能够定义一个人的全部，更不能决定其“人格”或“价值”。</strong></p>
<p>所以，当我们看到这张图时，不妨一笑置之。你可以开玩笑地对号入座，或者和朋友们讨论一下自己心目中不同技术栈组合的“开发者画像”，但请务必记住：</p>
<ul>
<li><strong>这纯属娱乐，切勿当真。</strong></li>
<li><strong>尊重每一个人的技术选择和个体差异。</strong></li>
<li><strong>警惕任何形式的标签化和刻板印象。</strong></li>
</ul>
<p>技术的魅力在于其多样性和解决问题的能力。无论你是“Embryo 1 号”、“Embryo 2 号”，还是任何其他独特的技术栈组合的拥趸，最重要的是享受编码的乐趣，创造有价值的软件，并在这个过程中不断学习和成长。</p>
<hr />
<p><strong>聊一聊，纯属娱乐大调查！</strong></p>
<ul>
<li><strong>看完这张图和解读，你觉得自己更接近“Embryo 1 号”还是“Embryo 2 号”的“技术基因”？或者你认为自己是哪种全新的“技术胚胎”？</strong></li>
<li><strong>在你心目中，使用特定编程语言/编辑器/操作系统的开发者，通常有哪些有趣的“刻板印象”？（欢迎在评论区开启“吐槽”模式，但请保持友好！）</strong></li>
<li><strong>你认为技术社区中，除了图上提到的，还有哪些常见的“鄙视链”或“部落文化”现象？我们该如何消解它们？</strong></li>
</ul>
<p>欢迎在<strong>评论区</strong>踊跃发言，分享你的“技术人格”自画像和趣味观察！如果你觉得这篇文章让你会心一笑，也请<strong>转发给你身边的开发者朋友们</strong>，一起加入这场轻松愉快的“技术对对碰”！</p>
<hr />
<p><strong>微专栏推荐：征服 Go 并发测试</strong></p>
<p>想彻底告别并发测试的“噩梦”吗？我的全新微专栏 <strong>《征服 Go 并发测试》</strong>（共三篇）现已上线！</p>
<p>本系列深入剖析并发测试痛点、testing/synctest 的设计原理与 API，并提供丰富的实战案例。助你轻松驾驭并发测试，写出更稳健的 Go 应用！</p>
<p><strong>微信扫码订阅，即刻解锁并发测试新境界！</strong></p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/paid/go-concurrent-test-qr.png" alt="" /></p>
<p><strong>更多微专栏，敬请期待！</strong> 对后续选题（如 Go 性能优化、AI 与 Go 结合等）有何期待或建议？欢迎在<strong>留言区</strong>畅所欲言，一起打造更精彩的内容！</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/07/nucleus-embryo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google I/O 2025 Go 语言进展：生产力、生产就绪与 AI 赋能</title>
		<link>https://tonybai.com/2025/05/25/go-at-googleio-2025/</link>
		<comments>https://tonybai.com/2025/05/25/go-at-googleio-2025/#comments</comments>
		<pubDate>Sun, 25 May 2025 00:26:55 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[cloudflare]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[FIPS-140]]></category>
		<category><![CDATA[firebase]]></category>
		<category><![CDATA[for-range]]></category>
		<category><![CDATA[fuzzing]]></category>
		<category><![CDATA[GC]]></category>
		<category><![CDATA[gemini]]></category>
		<category><![CDATA[genkit]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[go-get]]></category>
		<category><![CDATA[go1.18]]></category>
		<category><![CDATA[go1.23]]></category>
		<category><![CDATA[go1.24]]></category>
		<category><![CDATA[go1.25]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[GoogleIO]]></category>
		<category><![CDATA[Gopher]]></category>
		<category><![CDATA[gopls]]></category>
		<category><![CDATA[Iterator]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[langchaingo]]></category>
		<category><![CDATA[LLM]]></category>
		<category><![CDATA[map]]></category>
		<category><![CDATA[maps]]></category>
		<category><![CDATA[ollama]]></category>
		<category><![CDATA[POSIX]]></category>
		<category><![CDATA[RAG]]></category>
		<category><![CDATA[SIMD]]></category>
		<category><![CDATA[Slice]]></category>
		<category><![CDATA[strings]]></category>
		<category><![CDATA[terraform]]></category>
		<category><![CDATA[unique]]></category>
		<category><![CDATA[vscode]]></category>
		<category><![CDATA[wasi]]></category>
		<category><![CDATA[wasm]]></category>
		<category><![CDATA[wazero]]></category>
		<category><![CDATA[weak]]></category>
		<category><![CDATA[weaviate]]></category>
		<category><![CDATA[WebAssembly]]></category>
		<category><![CDATA[后量子密码学]]></category>
		<category><![CDATA[向量数据库]]></category>
		<category><![CDATA[垃圾回收]]></category>
		<category><![CDATA[漏洞]]></category>
		<category><![CDATA[生产力]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=4753</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/05/25/go-at-googleio-2025 大家好，我是Tony Bai。 在Google I/O 2025大会上，Go 产品负责人 Cameron Balahan 和开发者关系负责人 Marc Dougherty 详细阐述了 Go 语言在生产力、生产就绪度和开发者体验方面的最新进展及未来规划。演讲强调了 Go 语言以规模化为核心的设计理念及其三大指导原则：生产力、超越语言的完整体验和生产就绪。重点介绍了Go 1.23和Go 1.24版本在生产力方面的革新，包括引入迭代器简化循环、gopls 的智能现代化能力以及通过 go get 管理 Go 工具链；在生产就绪性方面，突出了 WebAssembly 支持的增强、安全体系的持续深化（特别是后量子密码学的透明集成和 FIPS-140 支持的便捷启用）以及核心性能的显著提升（如全新的 map 实现）。此外，演讲还强调了 Go 语言在 AI 基础设施构建中的核心地位，并展望了 Go 1.25+ 在 SIMD 支持、多核硬件优化等方向的探索，同时重申了 Go 1.0 的兼容性承诺。 这里是基于演讲视频，借助AI整理的文字稿，我做了简单校对和格式调整，供大家参考。 原视频链接：https://www.youtube.com/watch?v=kj80m-umOxs 建议大家也都看一下。 我是 Cameron，我是 Google Go 编程语言的产品负责人。我是 Marc，我负责 Go [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2025/go-at-googleio-2025-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/05/25/go-at-googleio-2025">本文永久链接</a> &#8211; https://tonybai.com/2025/05/25/go-at-googleio-2025</p>
<p>大家好，我是Tony Bai。</p>
<p>在Google I/O 2025大会上，Go 产品负责人 Cameron Balahan 和开发者关系负责人 Marc Dougherty 详细阐述了 Go 语言在生产力、生产就绪度和开发者体验方面的最新进展及未来规划。演讲强调了 Go 语言以规模化为核心的设计理念及其三大指导原则：<strong>生产力、超越语言的完整体验和生产就绪</strong>。重点介绍了<a href="https://tonybai.com/2024/08/19/some-changes-in-go-1-23">Go 1.23</a>和<a href="https://tonybai.com/2025/02/16/some-changes-in-go-1-24">Go 1.24版本</a>在生产力方面的革新，包括<a href="https://tonybai.com/2024/06/24/range-over-func-and-package-iter-in-go-1-23/">引入迭代器简化循环</a>、gopls 的智能现代化能力以及通过 go get 管理 Go 工具链；在生产就绪性方面，突出了 <a href="https://tonybai.com/2024/12/16/go-1-24-foresight-part1/">WebAssembly 支持的增强</a>、安全体系的持续深化（特别是<a href="https://tonybai.com/2025/05/22/go-mod-ignore-directive">后量子密码学的透明集成和 FIPS-140 支持的便捷启用</a>）以及核心性能的显著提升（如<a href="https://tonybai.com/2024/11/14/go-map-use-swiss-table">全新的 map 实现</a>）。此外，演讲还强调了 Go 语言在 AI 基础设施构建中的核心地位，并展望了 Go 1.25+ 在 SIMD 支持、多核硬件优化等方向的探索，同时重申了 Go 1.0 的兼容性承诺。</p>
<p>这里是基于演讲视频，借助AI整理的文字稿，我做了简单校对和格式调整，供大家参考。</p>
<p>原视频链接：https://www.youtube.com/watch?v=kj80m-umOxs 建议大家也都看一下。</p>
<p><img src="https://tonybai.com/wp-content/uploads/course-card/iamtonybai-banner-2.gif" alt="" /></p>
<hr />
<p>我是 Cameron，我是 Google Go 编程语言的产品负责人。我是 Marc，我负责 Go 的开发者关系。</p>
<p>对于那些刚接触我们项目的人来说，Go 是一个由 Google 支持的开源编程语言，它能让开发者和软件工程团队快速构建更安全、可靠和可扩展的生产系统。</p>
<p><a href="https://tonybai.com/2024/11/12/go-turns-15/">Google 在 15 年前将 Go 作为一个开源项目发布</a>，在此之前两年，Google 为了应对自身在构建和维护大规模、关键任务系统方面面临的挑战而启动了这个项目。使用现有的工具，我们不得不在动态解释性语言的生产力和强类型编译语言的生产就绪性之间做出选择。但<strong>我们两者都想要，所以我们构建了Go</strong>。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/go-at-googleio-2025-2.png" alt="" /></p>
<p>Go 的核心前提是开发工具从一开始就应该优先考虑可扩展性，这意味着要考虑到现代软件的架构方式、现代工作负载运行的环境，以及最重要的，编写、操作和维护这一切的团队。因此，考虑到这一点，我们围绕三个原则构建了Go，这些原则至今仍在指导着我们。</p>
<p>首先，Go 是高效的。它易于学习，易于维护，可读性强，并且能够很好地适应不同的团队、工作负载和用例。</p>
<p>其次，Go 不仅仅是一门语言，它是一个完整的开发者体验。从 IDE 到生产环境，我们提供端到端的解决方案，涵盖整个软件开发生命周期的所有接触点。我们提供所有这一切，开箱即用，并带有合理的、可自动调整的默认设置。</p>
<p>第三，Go 是生产就绪的。它可靠、高效、稳定且安全，这使得它非常适合从简单应用到企业系统和关键基础设施的各种场景。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/go-at-googleio-2025-3.png" alt="" /></p>
<p>多年来，Go 已经成为现代云计算的核心，并由此延伸到现代网络。世界上许多最知名的云技术都是用 Go 编写的，包括 Kubernetes、Docker、Terraform 等等。各种规模的公司，从个人到初创企业再到大型企业，都已采用 Go，尤其是在其基于云的工作负载方面。这在很大程度上是因为 Go 是为云计算而专门构建的。<strong>Go 所支持的库、集成和架构是为云而生的，而不是后来才为云进行改造的</strong>。这意味着你可以比使用其他语言更快、更容易地实现云计算的优势。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/go-at-googleio-2025-4.png" alt="" /></p>
<p>但你不必相信我的话。Go 用户一直给予我们非凡的反馈和客户满意度(注：93%)——这种水平在行业内几乎闻所未闻。使用情况也证明了这一点。如今，Go 比以往任何时候都更受欢迎，拥有数百万开发者，并且仍在快速增长。事实上，根据去年的NewStack的一项调查，Go 是仅有的两种增长速度超过开发者本身增长速度的语言之一。另一种是 Rust，我们认为它与 Go 配合得非常好，但这是另一个话题了。这样的迹象随处可见。Go 一直在 Stack Overflow 上被评为最受欢迎的技术之一。去年，Cloudflare 报告称，<strong>Go 是互联网上支持 API 调用的第一大语言</strong>。</p>
<p>因此，无论你是个人开发者、企业，还是介于两者之间的组织，Go 都能让你快速、更可靠地构建和扩展你的项目。你可能会很高兴你这样做了。接下来，Marc 将深入探讨 Go 的所有最新进展。交给你了，Marc。</p>
<p>谢谢，Cameron。Go 每年发布两次新的主版本，分别在八月和二月。在过去的一年里，我们在 1.23 和 1.24 版本中发布了许多令人兴奋的新功能，以帮助你和你的团队提高工作效率。</p>
<p>在1.23 版本中，我们引入了带有 seq 和 seq2 类型的迭代器。相较于经典的 Go 风格，迭代器不仅仅是标准库中的一个新类型。它们是一种优雅的方式，可以使用已经熟悉的 for range 表达式来简化循环，并将迭代的机制与循环体分开。在迭代器出现之前，有几种不同的方法来遍历数据。一些方法会返回一个包含所有结果的切片，这对于大型集合来说可能效率低下。另一种方法是创建自己的迭代器对象，就像这段代码一样，它使用了 Google Cloud Storage 库。注意这里的复杂性。我们的循环中有流程控制和错误检查。并且该错误检查需要在每个循环中重复。使用迭代器，你可以使用熟悉的 for range 语法来执行循环。复杂的流程控制则保留在迭代器内部。这使得我们的循环体可以专注于处理文件或错误，而无需担心流程控制。</p>
<p>从 1.24 版本开始，标准库在 strings、slices 和 maps 包中包含了一系列迭代器。因为迭代器只是一个函数，所以你可以定义自己的迭代器，包括为其他地方定义的集合类型定义迭代器。这是我为 Cloud Storage 示例定义的迭代器。声明看起来有点复杂，但你可以看到这里的流程控制与之前具有相同的效果。这个迭代器让我们能够将流程控制处理从循环中分离出来，并使它们更具可读性。</p>
<p>随着像迭代器这样的新概念的引入，Go 的垂直集成工具可帮助你的代码库与最新的模式和习惯用法保持同步。Go 的语言服务器 gopls 可以与你的 IDE 集成，既可以通过大多数 IDE 中的语言服务器支持，也可以通过插件（如 VS Code Go 扩展）实现。Gopls 在常规的语言服务器功能方面提供帮助，例如类型检查、函数签名和引用。但 gopls 的功能远不止于此。还记得那个复杂的迭代器定义吗？由于 gopls 从第一天起就知道新功能，因此它可以帮助你在编写时避免错误。在这里，它注意到了一个错误，即我们的迭代器可能会在应该停止后调用我们的 yield 函数。gopls 包含一套现代化功能，这些常见模式后来已作为语言特性或标准库新增功能得到解决。虽然你可以在整个代码库上运行现代化工具，但 gopls 可以在你编辑的任何地方内联建议它们。这里有一些旧模式的例子在左边，以及它们现代化的替代方案在右边。</p>
<p>最后一个现代化工具展示了 JSON 解析器的一个新特性，称为<a href="https://tonybai.com/2024/09/12/solve-the-empty-value-dilemma-in-json-encoding-with-omitzero/">omitzero</a>。JSON 包从 Go 1.0 开始就是 Go 的一部分。它通过简化 Go 结构体的序列化，实现了 API 客户端和服务器的人性化开发。omitzero 选项的添加解决了一些在处理 Go 的零值（如空结构体和未初始化的 time.Time 对象）时常见的错误和令人意外的行为。这些新增功能让你能够更好地控制对象如何序列化为 JSON，并避免可能的错误和混淆来源。</p>
<p>你是否需要更新你的 Go 运行时以利用新功能？从 1.23 版本开始，你可以使用 go get 来管理 Go 工具链，就像管理任何其他依赖项一样。Go 会根据需要下载更新的工具链，让你的团队可以使用最新的功能，而无需停下来手动更新工具链。这也适用于依赖项。如果你依赖了需要 1.24 版本的代码，Go 会更新你模块的 go 指令以要求 1.24 版本，并自动获取 1.24 运行时。Go 语言和 Go 工具不断寻找新的方法来帮助你保持代码库的可读性和现代化，并让你的团队保持专注和高效。</p>
<p>Marc 刚刚向你介绍了让你更高效的一些新功能。但请记住，Go 关注的是生产力和生产就绪性。那么，让我们来谈谈 Go 1.23 和 1.24 中那些让你的应用程序更健壮、更安全、性能更高的最新功能。</p>
<p>正如我之前所说，Go 的创始原则部分集中在其可移植性和对现代工作负载运行的现代环境的关注上。这些环境在不断发展。随着它们的发展，我们希望确保 Go 能够跟上步伐。我们做到这一点的一种方式是在 Go 1.24 中显著改进了 Go 对 WebAssembly 的支持。WebAssembly，或称 Wasm，是一种二进制指令格式和沙盒化运行时环境，它开启了许多新的有趣用例，尤其是在云端。包括 Go 在内的几种语言都能够编译 Wasm 模块，这些模块包含可在所有 Wasm 主机上运行的可移植的、与体系结构无关的字节码。同一个 Wasm 主机应用程序可以调用来自多个不同 Wasm 模块的方法，这些模块可以根据需要用一种语言或多种语言混合编写。这些 Wasm 模块是可热加载的，并在内存安全的沙盒化运行时中运行，具有结构化的控制流和验证。任何系统调用都通过 Wasm 运行时进行路由，这提供了一个额外的安全层，有点像一个极其轻量级的容器。尽管存在这一层抽象，但 Wasm 应用程序效率极高，能够在主机上实现接近本机的性能。这使得它们特别适用于高性能、低延迟的用例，例如边缘计算。例如，你可以在 Google Cloud 服务扩展上运行你的 Wasm 代码，它在 200 多个国家的 200 多个边缘位置提供边缘计算。</p>
<p>Go 在 Go 1.11 版本中通过 JS Wasm 移植首次引入了对 Wasm 的支持。Wasm 本身最初是为浏览器设计的。JS Wasm 移植通过允许你通过 JavaScript 主机定位网页，从而启用了此用例。Go 开发者利用这个功能制作了一些非常有趣的东西，尤其是游戏。甚至还有一些利用 JS Wasm 移植的 Go 开源游戏引擎。Go 开发者可以使用这些项目轻松开发在浏览器中运行的令人印象深刻的 2D 游戏。随着 Wasm 的发展，Go 也在发展。在 Go 1.21 中，我们引入了对 WebAssembly 系统接口（WASI）预览版 1 的支持。WASI 提供了一个 POSIX 风格的接口，用于与系统资源进行交互，例如文件系统、系统时钟、数据实用程序等等。在这个例子中，你可以看到一个简单的“Hello, world!”程序，我们通过开头的编译标志将其编译为 Wasm。然后我们可以使用众多免费开源的 Wasm 运行时和库之一来运行该程序。在这种情况下，我们使用的是 wazero，一个用 Go 实现的开源项目。从 Go 1.21 开始，Go 开发者可以将 Wasm 模块构建为可执行文件，在 Wasm 运行时中启动它，并运行至完成。</p>
<p>这就引出了今天的内容。在 Go 1.24 中，我们通过两种主要方式扩展了 Go 的 Wasm 功能。首先，Go 1.24 允许你使用 go:wasmexport 编译器指令将 Go 函数导出到 Wasm 主机。当我们将这样的代码编译成 Wasm 模块时，我们可以在 Wasm 主机中导入它，Wasm 主机可以直接调用模块导出的函数。其次，Go 1.24 添加了对构建 WASI 反应器 (reactor) 的支持。当你使用此功能以 Reactor 模式构建 Wasm 模块时，即使模块执行完毕，它也可以保持初始化状态。这对于你希望无限期可用的长时间运行的插件或扩展非常有用。初始化一次，让它保持运行，它可以继续响应调用，包括通过维护状态。在这个例子中，我们使用 wazero 的库来创建一个 Wasm 主机，它将调用我们在上一个例子中导出的 add 函数。不过，这次我们将使用高亮显示的构建标志以反应器模式构建 Wasm 模块。现在，我们可以多次运行 add 函数而无需重新初始化它。</p>
<p>接下来，我们来谈谈 Go 如何让你的应用程序更安全。Go 一直在安全特性和功能方面处于领先地位。在 Go 1.13 中，我们引入了模块代理和校验和数据库，它们缓存并记录 Go 生态系统中所有依赖项的哈希值，保护你免受中间人攻击和其他对依赖项的篡改。然后，在 Go 1.18 中，我们引入了内置的<a href="https://tonybai.com/2021/12/01/first-class-fuzzing-in-go-1-18">模糊测试 (fuzz testing)</a>，这是第一个将原生模糊测试内置并集成到其标准工具链中的主流编程语言。你可以将模糊测试视为一种自动化测试形式，它智能地操纵程序的输入以找出错误，尤其是安全漏洞。2022 年，我们推出了 Go 的端到端漏洞管理系统，它可以在任何地方（从 IDE 到运行时）发现依赖项中的已知漏洞。通过分析从你的代码到依赖项的调用图，<a href="https://tonybai.com/2022/09/10/an-intro-of-govulncheck">Go 的漏洞管理工具</a>能够检测你是否实际调用了易受攻击的代码，从而消除了绝大多数的误报。</p>
<p>基于我们对安全的关注，在 Go 1.24 中，我们引入了对<a href="https://tonybai.com/2025/05/20/post-quantum-cryptography-in-go">后量子密码学</a>的支持，所有这些都在幕后透明地实现。我们还改进了<a href="https://tonybai.com/2024/11/16/go-crypto-and-fips-140/">对 FIPS-140 的支持</a>，这是一项美国政府合规制度，其中包括用于加密应用的已批准算法。你可以在不更改任何代码的情况下启用 FIPS 模式，既可以在运行时使用高亮显示的调试标志，也可以在构建时使用高亮显示的构建 flag。</p>
<p>最后，我们继续专注于使 Go 更快、更高效。我们做到这一点的一个重要方式是引入了一个全新的内置 map 类型实现，它基于一种名为 Swiss Tables 的新哈希表设计。从 Go 1.24 开始，map 透明地使用新的 Swiss Table 实现。在微基准测试中，使用新实现的 map 操作比 Go 1.23 快了高达 60%，尤其是在处理大型 map 时。这一切都无缝集成在 Go 的内置 map 中。无需调整你的代码。只需升级即可。</p>
<p>还有更多，包括 Go 1.23 和 1.24 中许多新的底层工具，用于提高效率。例如，在 Go 1.23 中，我们引入了 <a href="https://tonybai.com/2024/09/18/understand-go-unique-package-by-example/">Unique Package</a>，可以高效地对值进行去重和比较。在 Go 1.24 中，我们引入了 <a href="https://tonybai.com/2024/09/23/go-weak-package-preview">weak.Pointers</a>，它允许你安全地指向一个对象而不会阻止它被垃圾回收，以及 AddCleanup 函数，这是一种更灵活、更高效且更不容易出错的终结机制。还有更多，包括改进的内存分配速度和整体速度提升。所有这些都延续了我们保持 Go 既高效又生产就绪的重点。</p>
<p>接下来，让我们把话筒转回给 Marc，让他快速介绍一下 Go 在生成式 AI 中的最新应用。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/go-at-googleio-2025-5.png" alt="" /></p>
<p>正如你刚才听到的，Go 拥有许多特性，使其成为构建生产系统的绝佳语言。像高效的网络库和集成的结构体标签这样的特性，使其非常适合构建分布式系统。这也是 Go 在云基础设施和服务中如此普遍的重要原因。同样的这些原因也使得 Go 成为当今构建 AI 基础设施和服务的绝佳选择。流行的生成式 AI 工具和库，如 <a href="https://tonybai.com/2024/05/09/text-vectorization-using-ollama-and-go-based-on-text-embedding-models/">Ollama</a>、Local AI、LangChain Go、Genkit 等等，都是用 Go 编写的。就像之前的主要基础设施项目一样，这些工具和库利用 Go 的生产力和生产就绪性来创建高度可扩展且更可靠的关键任务服务，数百万来自不同语言生态系统的开发者依赖这些服务来支持其 AI 驱动的工作负载。</p>
<p>事实上，云和 AI 系统之间的共同点比你想象的要多。由于 LLM 通常需要专用的、专门的计算资源，因此它们通常作为通过 API 调用的网络服务运行。让我们以 Go 博客最近一篇文章中概述的检索增强生成 (RAG) 系统为例。我们的 RAG 系统使用向量数据库来存储相关文档，以便在回答用户问题时提供给我们的 LLM。向量数据库依赖于专门的嵌入模型，因此我们可以高效地查询与用户问题相似的文档。我们将研究三种不同的框架，用于将这些服务连接在一起。</p>
<p>对于我们的第一个例子，我们将直接使用 Gemini 和 Weaviate 客户端库。这段代码来自用户查询处理程序。我们正在使用 Weaviate 的 GraphQL 接口来获取文档。查询本身有点长，所以我们使用了一个辅助函数。这种方法的一个缺点是，如果我们更改向量数据库，就必须重写辅助函数。</p>
<p>在这里，我们使用的是 LangChain Go，它为我们的 LLM 和向量数据库提供了接口抽象。如果我们替换这些组件，相似性搜索和从单个提示生成调用的代码将无需更改。</p>
<p>最后，我们来看看 Firebase Genkit for Go，目前处于测试阶段。它提供了与 LangChain Go 类似的抽象。Genkit 包含生产级功能，如提示管理和可观察性，这些功能可能在代码中不可见，但可以改善整体开发者体验。</p>
<p>随着你的 AI 系统的发展，Go 对简单性的强调意味着即使代码规模和复杂性增加，你的代码仍然保持可读性。Go 的特性，如对象嵌入和接口，使得在需求和技术发生变化时可以无缝迁移——而它们总是会发生变化。Go 在跟上快速变化方面的成熟能力使其在一些最知名的云基础设施组件中取得了成功。推动 Go 在云领域普及的相同特性，也使其成为我们构建未来 AI 基础设施的绝佳选择。</p>
<p>我希望我们已经在这个视频中证明了，Go 围绕生产力、开发者体验和生产就绪性的创始原则，仍然是我们今天优先考虑工作的依据。在结束之前，我想花几分钟时间让大家一窥 Go 1.25 及更高版本即将推出的内容。</p>
<p>首先，在 Marc 关于 AI 的讨论基础上，我们对<a href="https://tonybai.com/2024/07/21/simd-in-go/">围绕 SIMD 所做的工作</a>感到非常兴奋。SIMD 使现代 CPU 能够执行向量化数组操作，并行运行某些类型的循环。这些功能对于许多类型的性能优化至关重要，包括某些类型的 AI 基础设施所需的优化。</p>
<p>在性能方面，我们在多核硬件方面有很多令人兴奋的机会，包括<a href="https://tonybai.com/2025/05/03/go-green-tea-garbage-collector">垃圾回收器和调度器的功能</a>，这些功能可以更好地利用现代 CPU 架构中的非一致性内存访问。</p>
<p>切换到语言本身，在我们持续推动提高生产力方面，我们还有很多需要完善的地方，特别是在泛型操作的灵活性方面。有关该工作的更多信息，请查看我们在 GitHub 上 Go 项目的讨论。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/go-at-googleio-2025-6.png" alt="" /></p>
<p>在我们做所有这些以及更多事情的同时，你可以放心，我们现在和将来所做的任何更改都将继续履行 Go 的兼容性承诺。Go 仍然并将永远保持与 Go 1.0 的完全向后兼容。</p>
<p>在我们结束时，我们想花点时间感谢 Go 社区。我们，Go 团队，致力于在未来很长一段时间内保持 Go 的生产力和生产就绪性。但我们知道我们并不孤单。今天，我们的生态系统比以往任何时候都更大、更健全。我们继续看到许多非常高质量的工具和库涌现，尤其是在围绕生成式 AI 的新用例方面。我们看到世界各地成千上万的 Gopher 聚会、参加 Go 会议，并在网上协作，所有这些都是因为他们热爱 Go。所以，感谢 Go 社区。正是因为你们的贡献，Go 才得以发展，并且比以往任何时候都更具相关性。我们非常自豪能与你们一起参与这段旅程。</p>
<p>要开始使用，或获取有关本视频中讨论的任何内容的更多信息，请务必访问我们的主页 go.dev。感谢你参加今年的 Google I/O 大会。我们迫不及待地想看看你今年以及未来几年用 Go 构建的成果。</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>
<h2><img src="http://image.tonybai.com/img/tonybai/gopher-and-ai-tribe-zsxq-small-card.jpg" alt="img{512x368}" /></h2>
<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/05/25/go-at-googleio-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>
		<item>
		<title>Anders Hejlsberg专访全文：TypeScript正在向Go移植</title>
		<link>https://tonybai.com/2025/03/13/interview-with-anders-hejlsberg/</link>
		<comments>https://tonybai.com/2025/03/13/interview-with-anders-hejlsberg/#comments</comments>
		<pubDate>Wed, 12 Mar 2025 23:02:22 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[AndersHejlsberg]]></category>
		<category><![CDATA[bun]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Compiler]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[GC]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[porting]]></category>
		<category><![CDATA[Rust]]></category>
		<category><![CDATA[rxjs]]></category>
		<category><![CDATA[TS]]></category>
		<category><![CDATA[TypeScript]]></category>
		<category><![CDATA[vscode]]></category>
		<category><![CDATA[Zig]]></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=4506</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/03/13/interview-with-anders-hejlsberg 昨天发表了《Anders Hejlsberg亲自操刀向Go语言移植！TypeScript编译器性能狂飙10倍！》一文后，收到了许多读者的反馈，其中最高频的问题是：为什么不选择Rust？为什么不使用C#等其他语言？为了帮助大家更好地理解这次“技术事件”，我整理了Michigan TypeScript对Anders Hejlsberg的专访的文字稿（时长超过1小时），并将全文发布在这里供大家参考。 注：由于专访内容较为丰富，文字稿是通过工具提取油管视频字幕，并由AI进行格式化整理后整体翻译，最后经过人工校对而成。因此，文中可能存在翻译不当之处，敬请谅解。 主持人： JavaScript 本身并不是为了计算密集型的系统级工作负载设计的，对吧？而 Go 恰恰是为此而生。我们追求的是完全兼容，希望能提供旧编译器的即插即用替代品。但我认为更有意思的是，思考类型检查器速度提升十倍意味着什么。当它与当下的人工智能和智能编程结合起来，我们如何利用这些信息？例如，为大型语言模型（LLM）提供上下文信息：这些类型实际解析成了什么？这个符号是什么？在哪里声明的？因为现在 LLM 只能看到拼写，并不理解其含义。所以我们可以实时地赋予它更高保真度的信息。TypeScript 类型检查器，作为软件开发中最基础的工具之一，今天宣布团队经过数月的努力，将代码库移植到 Go，速度提升了十倍。当 TypeScript 首席架构师和联合创始人 Anders Hejlsberg 主动提出与我讨论这项重大变革时，我努力从库作者、高级用户、工具开发者和编译器贡献者的角度出发，思考他们可能有的问题。我主要使用 Rust 进行开发，我知道很多人会问：为什么不选择 Rust？我也是第一时间有这个想法。但在与 Anders 的对话中，他分享了团队对未来方向的愿景。在听取了他的技术原因后，我完全认同Go才是正确的选择。我希望大家关注的重点，不是选择了哪种原生语言，而是类型检查速度提升十倍，内存占用减半，以及并发能力。这将让 TypeScript 更加有趣，并带来无限可能。希望大家能享受这次与 Anders 交流的机会。大家好，欢迎 Anders Hejlsberg 的到来！TypeScript 世界正发生着一件大事，他将在这里与我们探讨并解答疑问。希望能从库作者以及深度使用 TypeScript 用户的角度，提出一些问题，并听取他的观点。Anders，你好吗？请简单介绍一下自己吧。 Anders Hejlsberg： 我很好。我是 Anders Hejlsberg，微软技术院士，也是 TypeScript 开源项目的首席架构师。在此之前，我在 C# 上工作了十多年。更早之前，我在 Borland 公司从事 Delphi 和 Turbo Pascal 的开发工作。总的来说，我从事软件开发，尤其是编程语言和软件开发工具，已经差不多 40 年，甚至更久。 [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/interview-with-anders-hejlsberg-1.jpg" alt="" /></p>
<p><a href="https://tonybai.com/2025/03/13/interview-with-anders-hejlsberg">本文永久链接</a> &#8211; https://tonybai.com/2025/03/13/interview-with-anders-hejlsberg</p>
<p>昨天发表了《<a href="https://tonybai.com/2025/03/12/typescript-native-port-to-go/">Anders Hejlsberg亲自操刀向Go语言移植！TypeScript编译器性能狂飙10倍！</a>》一文后，收到了许多读者的反馈，其中最高频的问题是：为什么不选择Rust？为什么不使用C#等其他语言？为了帮助大家更好地理解这次“技术事件”，我整理了<a href="https://x.com/MiTypeScript">Michigan TypeScript</a>对<a href="https://www.youtube.com/watch?v=10qowKUW82U">Anders Hejlsberg的专访</a>的文字稿（时长超过1小时），并将全文发布在这里供大家参考。</p>
<blockquote>
<p>注：由于专访内容较为丰富，文字稿是通过工具提取油管视频字幕，并由AI进行格式化整理后整体翻译，最后经过人工校对而成。因此，文中可能存在翻译不当之处，敬请谅解。</p>
</blockquote>
<hr />
<p><strong>主持人：</strong></p>
<p>JavaScript 本身并不是为了计算密集型的系统级工作负载设计的，对吧？而 Go 恰恰是为此而生。我们追求的是完全兼容，希望能提供旧编译器的即插即用替代品。但我认为更有意思的是，思考类型检查器速度提升十倍意味着什么。当它与当下的人工智能和智能编程结合起来，我们如何利用这些信息？例如，为大型语言模型（LLM）提供上下文信息：这些类型实际解析成了什么？这个符号是什么？在哪里声明的？因为现在 LLM 只能看到拼写，并不理解其含义。所以我们可以实时地赋予它更高保真度的信息。TypeScript 类型检查器，作为软件开发中最基础的工具之一，今天宣布团队经过数月的努力，将代码库移植到 Go，速度提升了十倍。当 TypeScript 首席架构师和联合创始人 Anders Hejlsberg 主动提出与我讨论这项重大变革时，我努力从库作者、高级用户、工具开发者和编译器贡献者的角度出发，思考他们可能有的问题。我主要使用 Rust 进行开发，我知道很多人会问：为什么不选择 Rust？我也是第一时间有这个想法。但在与 Anders 的对话中，他分享了团队对未来方向的愿景。在听取了他的技术原因后，我完全认同<strong>Go才是正确的选择</strong>。我希望大家关注的重点，不是选择了哪种原生语言，而是<strong>类型检查速度提升十倍，内存占用减半，以及并发能力</strong>。这将让 TypeScript 更加有趣，并带来无限可能。希望大家能享受这次与 Anders 交流的机会。大家好，欢迎 Anders Hejlsberg 的到来！TypeScript 世界正发生着一件大事，他将在这里与我们探讨并解答疑问。希望能从库作者以及深度使用 TypeScript 用户的角度，提出一些问题，并听取他的观点。Anders，你好吗？请简单介绍一下自己吧。</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>我很好。我是 Anders Hejlsberg，微软技术院士，也是 TypeScript 开源项目的首席架构师。在此之前，我在 C# 上工作了十多年。更早之前，我在 Borland 公司从事 Delphi 和 Turbo Pascal 的开发工作。总的来说，我从事软件开发，尤其是编程语言和软件开发工具，已经差不多 40 年，甚至更久。</p>
<p><strong>主持人：</strong></p>
<p>多么令人惊叹的职业生涯！我记得不久前，我还对 C# 开发充满热情，并对其赞赏有加。感谢您对此做出的贡献！但后来 TypeScript 出现了。那么，我们从头开始吧。</p>
<p><strong>主持人：</strong></p>
<p>这个新项目的代号是 Corsa，对吗？ 而旧代码库则被称为 Strata。我碰巧知道 Strata 也是 TypeScript 最初的代号，是真的吗？</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>没错。那是我们刚开始项目时的代号，大概是 2010 年末或 2011 年初。那是我们在内部开发的前几年的代号。</p>
<p><strong>主持人：</strong></p>
<p>是您和 Luke 吗？</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>还有 Steve，当然，Steve Lucco。他编写了最初的原型编译器。他实际上是从 Internet Explorer 的 JavaScript 引擎中提取了扫描器和解析器，然后进行了改造。那是一个 C# 代码库，只是为了进行概念验证。Luke 当时是我们的产品经理。所以 Steve、我和 Luke 是 TypeScript 的最初团队。</p>
<p><strong>主持人：</strong></p>
<p>太棒了！那么，快进到……我不太清楚具体时间，也许您可以告诉我。Corsa 这个新方向是谁提出的？具体是哪一天？</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>我不确定有没有一个确定的日子。这个想法已经在我们脑海里酝酿很久了。在 ECMAScript 社区中，一直存在一种趋势，即将一些高度依赖的工具迁移到原生代码，比如 esbuild 和 swc 等等。现在已经有很多用于 JavaScript 的原生代码解析器和 Linter。我们一直在关注这一点，也看到许多人尝试构建 TypeScript 的原生代码版本。其中大部分是从第一性原理开始，有些尝试移植，但都没有达到关键规模。这也可以理解，因为这是一个复杂的项目。我们已经投入了大约 100 人年的工作到 TypeScript 中。所以，单个人试图移植或创建一个高度兼容的版本，都是一项艰巨的任务。但我们一直在关注社区中发生的所有这些事情。</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>性能和可扩展性一直是用户最主要的需求。他们希望能够更好地扩展，运行速度更快。所有软件都是这样，没有东西会变小，只会变大。项目越来越大，我们的编译器也越来越大。反过来，这也给 V8 和 JavaScript 引擎带来了更大的压力。因为 JavaScript 是一个即时编译（JIT）环境，所以我们的启动时间也在随着新功能的添加而不断增加。因此，我们看到启动时间缓慢增长，或者说速度减慢。我们一直努力提升性能，也做了一些工作，但所有的优化都只有 5% 或 10% 左右，没有产生质的飞跃。我们逐渐意识到，这可能就是<strong>我们所能达到的优化极限了</strong>。当我们查看编译器的性能分析时，并没有发现任何热点。它已经在尽其所能地运行，以完成需要完成的工作。</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>长话短说，在八月份，我们开始思考：我们需要收集一些数据，了解移植到原生代码意味着什么，以便做出明智的决定，是否值得这样做。我们开始用不同的语言构建原型，比如 Rust、Go、C++ 等等。我们认为<strong>Go是一种非常适合我们需求的语言</strong>。所以在八月份，我开始移植扫描器和解析器，只是为了获得一个基准，看看速度能有多快，以及从 JavaScript 移植到 Go 有多困难。实际上，进展相当顺利。在几个月内，<strong>我们就得到了可以运行的东西，能够解析我们所有的源代码，没有任何错误</strong>。我们可以开始从中推断出一些数字。那时我们开始意识到，<strong>我们可以实现 10 倍的性能提升</strong>。因为我们可以从原生获得大约 3 到 3.5 倍的提升，然后从并发获得另外 3 到 3.5 倍的提升。两者结合起来就达到了 10 倍。10 倍的提升是非常显著的。一旦你看到这个可能性，你就会觉得很难放弃。其他的一切都黯然失色。</p>
<p><strong>主持人：</strong></p>
<p>团队的其他成员对此怎么看？我想总有一天，大家会意识到用 Go 这种方法或许可行。团队其他成员的反响如何？</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>我认为这是一种兴奋与担忧的混合。因为这是一个完全未知的领域。我们真的能成功吗？人们能否在合理的时间内掌握 Go 语言？Go 的工具链怎么样？它们是否能像 TypeScript 本身一样优秀？毕竟，我们已经使用 TypeScript 编写 TypeScript 十多年了。所以，既有很多未知数，同时也对潜在收益感到兴奋。</p>
<p><strong>主持人：</strong></p>
<p>你提到了自举。对于听众而言，自举语言是指用其自身编写的语言。很多语言都是从其他语言开始的，比如 Go 最初是用 C 编写的，Rust 最初是用 OCaml 编写的。但是在获得了一些关键代码之后，就可以用该语言描述自身。TypeScript、Go 和 Rust 都变成了自举语言。那么，放弃自举语言有什么其他例子吗？</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>我认为，所有其他迁移到 JavaScript 生态系统中原生代码的工具，都放弃了自举，因为它们最初就是用 JavaScript 编写的。我们最大的担忧之一就是放弃自举，因为自举对我们帮助很大。我相信我们仍然会保留一些用 JavaScript 编写的部分。有多少，还有待观察。我们仍在探索语言服务的解决方案。我们知道语言服务的核心需要使用原生代码编写，也就是语义引擎。编译器负责提供所有信息，但周围有很多东西仍然可以用 JavaScript 编写。我们知道我们需要在原生部分、Go 以及想要从其他语言消费的消费者之间构建 API。这仍然是我们尚未完全解决的问题。但我们绝对看到了自举的价值。但另一方面，<strong>我们也是现实主义者。很难永远放弃 10 倍的性能提升</strong>。一方面和另一方面，哪种选择对社区更有益？</p>
<p><strong>主持人：</strong></p>
<p>绝对的。我希望人们能从这次谈话中得到这个信息。我应该提到，我也是一名 Rust 开发者。当我听到这个消息时，我感到非常兴奋。我认为很多人都会想问：为什么不选择 Rust？因为社区中很多工具都在向 Rust 靠拢。我想直接问你，是否考虑过 Rust？我知道你说你看过它。我也想了解一下为什么不选择 C#？据我所知，自从我上次看 C# 以来，它在异步和线程池方面有了很大的进步。能否谈一谈这些？</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>我认为这里的一个主要因素是，我们正在进行移植，而不是从头开始。如果我们从头开始，那么对语言的选择就可以围绕着你的项目来构建。如果我们从头开始，用 Rust 编写，那么我们会设计一个从一开始就不依赖自动垃圾回收，也不依赖循环图等等的编译器。从第一性原理出发，当你有一个已经使用了十年以上，拥有数百万程序员和无数行代码的产品时，你将会面临大量的兼容性问题。因为我们的编译器中有很多行为是可以说是“任意”的。当我说是“任意”的时候，我指的是类型推断。例如，可能有多个候选类型都是正确的，我们选择其中一个。从某种意义上说，这是一种程序所依赖的行为。如果在新的代码库中，行为有所不同，那么你可能会看到新的错误。所以从一开始，我们就知道唯一有意义的方法就是移植现有的代码库。<strong>现有的代码库做出了一些假设，特别是它假设存在自动垃圾回收。我认为这几乎限制了我们的选择。Rust 基本上就被排除了</strong>。因为在 Rust 中，你可以进行内存管理，但它不是自动的。你可以使用引用计数等等。除了这一点，还有借用检查器及其对数据结构所有权的严格约束。特别是，它有效地禁止了循环数据结构。我们所有的数据结构都大量使用循环。我们有抽象语法树（AST），其中包含子指针和父指针。我们有带有声明的符号，这些声明指向了引用回符号的节点。我们有循环引用的类型，因为它们是递归的。试图理清所有这些，将会极大地增加迁移到原生代码的难度，如果我们还必须要重新设计所有这些。</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>当我们列出我们所需的语言时，我们希望该语言能够在所有主流平台上提供卓越的、优化的原生代码。我们希望该语言具有良好的数据结构表达能力，允许循环数据结构，也允许内联数据结构，比如结构体。这样我们就可以避免在 JavaScript 中对每个对象都进行内存分配。如果能将小对象内联存储，我们希望能尽量避免这种情况。我们需要自动垃圾回收。我们也知道，我们需要并发，并且需要共享内存的并发。我们可以讨论其中的区别。从技术上讲，JavaScript 拥有 Web Workers，可以实现并发，但它并没有共享内存的并发。我可以解释为什么我们需要它来实现编译器。这也是必须的。当你考虑所有这些因素，以及良好的工具链，比如 VS Code 的优秀支持等等，Go 实际上成为了一个非常有吸引力的选择。这就是我们开始在 Go 中进行原型设计，并发现这是一种很棒的体验，并继续深入的原因。</p>
<p><strong>主持人：</strong></p>
<p>我认为这才是关键。我热爱 Rust，但这种热情不会蒙蔽我，让我无法说出 Rust 并不具备“周末速成”的特性。Rust 似乎非常注重尽可能做正确的事情，即使以牺牲开发者体验为代价。</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>是的，而且我坚信，<strong>如果你来自 JavaScript，你会发现过渡到 Go 比过渡到 Rust 更加容易</strong>。</p>
<p><strong>主持人：</strong></p>
<p>很高兴听到你这么说。我认为这从人力资源的角度来说，是另一个使这个决定有意义的重要原因。如果你查看一些 JavaScript 代码，然后查看用 Go 实现的相同代码，它们看起来很相似。但是如果你查看用 Rust 实现的相同代码，特别是如果遇到任何特别复杂的事情，或者像你提到的递归结构，那么就很难理解 Go 代码是如何从 TypeScript（也就是 JavaScript）代码演变而来的。我之前也做过这种事。我认为这是 Go 的一个优势。</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>您说的很有道理。</p>
<p><strong>主持人：</strong></p>
<p>那么，为了完成这个循环，请再谈谈 C#。为什么没有考虑 C# 呢？</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>C# 也在考虑范围内。但我认为 Go 无疑是……我认为它是<strong>我们能达到的最低级别的语言，同时还具有自动垃圾回收功能</strong>。它是我们能达到的最以原生为先的语言，同时仍然具有自动垃圾回收功能。C# 有点像是字节码优先，如果你愿意这么说。虽然有一些提前编译可用，但并非在所有平台上都可用。它并没有经过长达十年的强化，从一开始也并非以这种方式设计。我认为 Go 在数据结构布局和内联结构体方面具有更强的表达力。</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>我想补充一点，我们的 JavaScript 代码库是用高度函数式编程风格编写的。我们很少使用类。事实上，核心编译器根本不使用类。这也是 Go 的一个特点。Go 是函数和数据结构。而 C# 则主要面向面向对象编程（OOP）。为了迁移到 C#，我们需要切换到 OOP 范式。这又增加了迁移过程的摩擦。所以最终，这条路对我们来说是阻力最小的。</p>
<p><strong>主持人：</strong></p>
<p>好的。我对这个问题有一些疑问。我过去在使用 Go 进行函数式编程时遇到过很多困难。我很高兴听到您认为这不是什么问题。这是我一开始想问的。</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>当我说函数式编程时，我指的是一种纯粹意义上的函数式编程。也就是说，我们主要处理的是函数和数据结构，而不是对象。我不是在谈论模式匹配、高阶类型和单子(monad)之类的概念。我们处于一个更低的层次。</p>
<p><strong>主持人：</strong></p>
<p>明白。当你查看 TypeScript 代码库时，我贡献得不多，但我经常通过调试来试图理解内部机制。我在调试 TypeScript 代码库编译输出时，经常遇到的一个问题是，TypeScript 代码库大量使用枚举和按位运算，尤其是对枚举进行一元按位运算来跟踪值。Go 并没有完全类似的东西。Go 可以将常量分组在一起，看起来有点像枚举。我很好奇 TypeScript 代码库中这个非常普遍的特性是否受到了影响？或者说，Go 如何解决这个问题？</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>我认为你真正想说的是，TypeScript 拥有比 Go 更加丰富的类型系统。我完全承认这一点。Go 确实没有像枚举这样的概念，尽管它可以将常量组合在一起并自动编号。这有点古怪。虽然对它进行一些类型检查，但 Go 实际上对位操作和将标志打包成整数有很好的支持。事实上，<strong>Go 对各种数据类型的支持比 JavaScript 更好</strong>。你可以使用字节、短整型、整型以及 64 位整型，包括有符号和无符号类型。而在 JavaScript 中，一切都是浮点数。如果你想表示true或false，就需要 8 个字节。这真是太麻烦了。这就是为什么我们在现有的编译器中采取了各种各样的技巧。至少我们可以将 31 位压缩到一个浮点数中。但在 Go 中，我们可以使用所有的位。而且，我们还可以将它们布局为结构体，进行内联存储。我们的内存消耗大约只有旧编译器的一半。在这个时代，内存就等于速度。你使用的内存越多，速度就越慢，因为你访问内存屏障或读屏障的次数就越多，最终需要访问真正的内存。在现代 CPU 中，每条指令都需要零个时钟周期（因为预测），除非它需要一千个时钟周期，因为你遇到了内存瓶颈。如果你能压缩你的数据结构，就能获得更快的速度。</p>
<p><strong>主持人：</strong></p>
<p>你让我开始思考，尽管 Go 的类型系统不像 TypeScript 那么高级，但它仍然有一些与众不同之处。我过去使用 Go 时最怀念的一点是不透明类型的概念。你可以在 TypeScript 中创建一个类型的别名，现在人们经常这样做，我们称之为“branded types”。我很好奇，据我所知，F# 在 Strata 和 TypeScript 的早期阶段产生了一些影响。您在日常编写 Go 的过程中是否受到了什么影响？在 Go 中有没有看到任何让你觉得可以引入到 TypeScript 中的东西？</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>你是说反向影响吗？</p>
<p><strong>主持人：</strong></p>
<p>是的。</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>很有意思。让我想一想。顺便说一句，我想提一下，更高版本的 Go 实际上引入了“新鲜类型(fresh types)”的概念。你可以拥有一个与其它int32不同的新鲜int32。这就是我们为枚举提供类型安全的方式，因为我们为每个枚举声明了新鲜类型。但有没有什么能够反过来影响 TypeScript 的东西呢？这很困难，因为 Go 作为一个类型系统…… 我不会说它平庸，但它是一个相当简单的类型系统。有一些运行时特性我希望拥有，但现在我们谈论的是 JavaScript 运行时。当然，结构体对我们帮助很大，但它是否一定对整个 JavaScript 社区有益，我就不太确定了。</p>
<blockquote>
<p>译注：这里提到的新鲜类型似乎是使用type关键字自定义一个具名新类型。</p>
</blockquote>
<p><strong>Anders Hejlsberg：</strong></p>
<p>像编译器这样的程序，实际上是一种非常特殊的，在 JavaScript 运行的东西。我经常开玩笑说，如果有人告诉我，我会用 JavaScript 编写编译器十年，我会觉得简直是胡说八道。但在某种程度上，这就是我一直在做的事情，或者说我们的团队一直在做的事情。但 JavaScript 本身就不是为计算密集型的系统级工作负载而设计的。Go 恰恰是为此而生。看看 Kubernetes 和其他用 Go 编写的重要项目。<strong>Go 基本上缺乏任何 UI 抽象。Go 是一种系统级工具，而我们也是一个系统级的程序。所以这很有意义，这是一种很好的结合</strong>。</p>
<p><strong>主持人：</strong></p>
<p>那么，让我们深入探讨一下如何确保这次重大变革能够平稳过渡到生态系统中。首先我想到的一个问题是：TypeScript 并没有正式的规范。引用实现有点像是规范。你们将如何从这种状态过渡到新的代码库，并保持一切一致呢？</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>这特别强调了我们进行移植的核心原因之一。当你移植代码时，最终会得到相同的语义。你会得到不同的代码，但语义是相同的。这意味着当你输入数据并期望某种行为时，会发生相同的事情。</p>
<p><strong>主持人：</strong></p>
<p>所以你不会看到任何差异吗？</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>不，非常忠实于旧版本。我们拥有所有相同的类型。它的布局方式与 JavaScript 中相同。当然，在 JavaScript 中声明它时，我们大量使用联合类型和交叉类型等等，以及所有在 Go 中无法实现的花哨的东西。所有的类型定义看起来都会有所不同。但在语义上，我们谈论的是同一件事。对于编译器本身的符号和类型对象模型也是如此。</p>
<p><strong>主持人：</strong></p>
<p>很高兴听到这一点，因为我认为库作者会担心他们是否必须维护两个版本的类型定义。听起来你们会付出很多努力来确保过渡的顺利进行。</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>我们的目标是 99.99% 的兼容性。理想情况下，我们希望对相同的代码库产生完全相同的错误。这就是我们一直在努力的方向。目前，<strong>我们现在开源的编译器可以编译并检查所有 Visual Studio Code，没有任何错误</strong>。这是一百五十万行代码，大约有 5000 个源文件和 50 兆字节的源代码。我们正在接近启用所有测试。我们知道我们可以运行 20,000 个符合性测试而不会崩溃。我们仍在分析错误基线等等，并努力消除一些差异。我们追求完全的兼容性。我们真的希望它能成为旧编译器的即插即用替代品。因为这是我们摆脱需要永远维护旧编译器困境的唯一途径。</p>
<p><strong>主持人：</strong></p>
<p>您认为今天有什么让您觉得，这将是过渡中最艰巨的挑战吗？如果答案是否定的，那也是个好答案。</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>不，我认为仍然存在一些挑战。有些事情是必然存在的，使得情况变得复杂。实际上，这需要很长时间才能解释清楚。但有些事情我们必须要改变，特别是关于以确定性方式对类型进行排序。我对类型排序的理解是：当你有一个类型的联合时，有时顺序很重要。比如打印联合类型时，顺序很重要。但是在某些情况下，当我们选择报告错误的候选类型，或者进行子类型缩减等操作时，顺序也很重要。在旧的编译器中，我们使用了一种非常简单但非确定性的类型排序方式。在单线程上，它是确定性的。无论何时实例化或者创建一个表示类型的对象，我们都只会给它一个序列号，然后不断地递增这个序列号。如果再次编译，所有类型都会获得相同的序列号，一切都一遍又一遍地相同。但是，当你在多个核心上运行，并有多个类型检查器，或者说事情以稍微不同的顺序进行检查时，就会变成非确定性的。因为这就是并发的本质。</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>因此，我们需要引入确定性的类型排序。当然，这意味着现在我们的类型顺序在某些情况下与旧的编译器不同。虽然联合类型不应该是有序的，但在某些情况下，顺序确实很重要。所以我们必须要解决这些问题。但这绝对是可行的。我认为最大的挑战在于如何为新的代码库提供一个可版本化和现代的 API。因为不管是好是坏，在我们的旧代码库中，源代码也成为了我们的 API 规范。嘿，它是 JavaScript！你可以从任何地方调用任何函数。而且人们也确实会这么做。编译器的所有内部结构都有效地暴露为 API。这在未来是行不通的。因为我们的代码已经从暴露编译器的每个函数，变成了暴露零个函数。它完全是一个黑盒。现在我们需要仔细考虑，如何在这个代码库上放置一个 API，以及如何在必须在进程之间切换，通过通信通道进行通信，而不是直接将数据推送到堆栈并进行函数调用的情况下，保证这个 API 的效率？</p>
<p><strong>主持人：</strong></p>
<p>我完全明白你的意思。我有一些项目也在做你说的事情。如果你调用函数，它就在那里。但如果你查看类型定义，它已经被删除了。但如果你调用该函数，它仍然可以工作。人们确实会这样做。你抓到我了，这很有趣。</p>
<p><strong>主持人：</strong></p>
<p>我的意思是，很高兴听到您一直在考虑 JS API。我们可以谈谈连接点吗？我想说的是，我很高兴它不是用 Rust 编写的，因为我认为这只会加强与其他语言的连接点，并带来更多的可能性。如果我想用 Zig 编写一个发射器，我觉得如果整个 API 是……虽然你没有提到 WebAssembly，但我很好奇其中是否有 WebAssembly 组件，或者如何提供这些？你会有 Rust 绑定吗？或者你会有与其他语言的绑定吗？</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>我认为我们肯定会有语言中立的绑定。我们肯定会提供的一个绑定是语言服务器协议 (LSP)。因为我们正用它来实现新的原生语言服务。顺便说一句，我们已经希望进行这种转变很多年了。TypeScript 项目早于语言服务器协议，而且实际上是语言服务器协议的灵感来源。但是，我们自己从来没有过渡到 LSP。我们正在借此机会完成过渡。这将是一个在任何地方都可以使用的 API。当然，您也可以想象我们添加除了核心 LSP 功能之外的额外功能，让你能够以语言中立的方式向语言服务器询问不同的问题。但它永远无法达到当前 JavaScript API 的丰富程度。我们正在探索能够提供更丰富、更同步的 API 的解决方案。因为如果我们要继续用 JavaScript 构建部分语言服务，我们自己也需要这个。现在说清楚所有这些将如何发展还为时过早。但我们肯定正在那个领域进行大量的探索。</p>
<p><strong>主持人：</strong></p>
<p>明白了。您预计 Strata 代码库会维护多长时间？即使在您认为 Go 代码完全普遍可用之后？</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>我认为大概还有几年时间。这只是因为我们天性保守。我们不想抛弃任何人。我们知道有一些项目需要按照他们的方式运行，而且我们还没有在新的原生编译器中为他们提供解决方案。但我预计到今年年底，我们就能拥有一个功能齐全的编译器，大多数人都能够使用。我们已经非常接近命令行编译器了。我想我们会在夏天或晚春实现这个目标，到那时人们就可以直接使用它了。当然，仍然有一些部分尚未完成。我们还没有支持 JSDoc 或 JSX，虽然这正在进行中。我们还没有支持项目引用，构建模式以及 watch 模式等等。但这些也都在进行中。所以一切都在陆续上线。但我们确实已经拥有了一个编译器，它可以编译单个项目，速度比旧编译器快 10 倍，并且如果出现错误，会给出相同的错误信息。</p>
<p><strong>主持人：</strong></p>
<p>您认为这两个代码库最终会合并吗？还是 TypeScript Go 代码库会成为 TypeScript 的未来？</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>从长远来看，<strong>Go 代码库会成为我们的未来</strong>。但正如我所说，我们仍在探索如何构建语言服务。肯定会有语言服务的原生组件，但也可能会有 JavaScript 组件。当然，这个组件会用 JavaScript 或 TypeScript 编写。</p>
<p><strong>主持人：</strong></p>
<p>很高兴知道您一直在考虑如何管理这个过渡过程。您刚刚给出了一个非常激进的时间表，但是它也是一个长期的支持计划。我的朋友 Andrist 之前在您的频道出现过，我相信您认识他。现在他好像有 100 个 PR 处于 open 状态。我曾想，Andrist 的 PR 会发生什么？但听起来它们是安全的，希望我们能够移植它们。</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>希望我们会移植它们。实际上，我们在八月份的某个随机提交点进行了快照。我们选择了特定的提交，然后说：这就是我们要移植的提交，源代码就以此状态为基准。从那时起，我们就可以回去查看此后合并的所有 PR，我们可以挑选并翻译或移植它们。我们会进行后续工作，这将会并行进行。我相信我们能做到。</p>
<p><strong>主持人：</strong></p>
<p>太好了。我想这个答案会对工具开发者们产生很大的鼓舞。我想问一下，您认为工具开发者，比如 linter、格式化工具和依赖分析工具等，是否应该期望他们的工具在类型检查方面也能够更快呢？</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>这是一个很难回答的问题。这完全取决于具体的工具，以及它如何利用语言服务。这取决于它是大量依赖于编译器的语义服务，还是只使用了原生解析器。情况各不相同。我想说的是，我们正在与生态系统中大部分知名的工具开发者进行对话。如果还没有，我们也会主动与他们进行交流。我们会尽力帮助他们将功能进行移植、向量化，或者进行其他任何必要的处理。</p>
<p><strong>主持人：</strong></p>
<p>听到您在直接与 linter 开发者和格式化工具作者沟通，这令人感到安心。我认为这将极大地有助于每个人都能平稳过渡。谢谢您这样做。</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>这是我们应该做的。这实际上是一个很好的过渡，可以讨论一下……我想再问一个关于并发的问题。您提到并发模型带来的差异也会对 JS API 造成一些挑战。您投入了多少精力在并发上？增加并发有多困难？您是否花时间调试死锁或并发问题？</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>很有趣。因为我们正在移植的编译器，也就是每个人过去十年一直在使用的 TypeScript 编译器，正如我之前所说，它本身就是一个非常函数式的代码库。这意味着它采用了函数式编程模式，特别是大量使用了不可变性，以确保安全共享。例如，在扫描、解析和绑定抽象语法树之后，我们基本上就认为该语法树是不可变的。这意味着多个类型检查器可以同时处理同一个 AST。您可能会问，但 JavaScript 没有并发，为什么这很重要？这是有一定意义的，因为你可能同时打开多个包含相同文件的项目。这节省了我们创建多个重复 AST 的麻烦。另外，这使得我们更容易复用数据。因为请思考一下，当您在语言服务中编辑文件时，您实际上是在不断地创建一个新的程序。因为该文件在不断发生变化。这意味着整个程序也在不断变化。现在，大部分内容并没有改变。因此，当你重建整个程序视图（这是类型检查器所需要的）时，您希望尽可能多地重用旧的程序视图。这就是使用不可变数据结构非常重要的原因。在一个包含 100 个文件的项目中，当您仅修改一个文件时，对于每次击键，您都需要重建一个全新的程序视图。您可以直接使用 99 个未修改的文件及其 AST，而只关注您正在编辑的文件。</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>从一开始，我们的编译器就以这种方式设计的。几乎可以说，这是一个非常适合并发的编译器，但是它被限制在一个无法访问所需并发类型的“盒子”中。这就是我之前提到的共享内存并发。这一点非常重要。思考一下如何在我们的编译器中使用并发。例如，解析就是一个非常适合并行化的任务。它包括将源文件读入内存，然后构建一个数据结构，使您可以浏览该源文件。现在，将源文件读取到内存中只需要获取一个字符串并将其放入内存中即可。然后，构建一个数据结构，使您可以快速浏览该字符串，并找到特定的位置，例如字符串中的 token、函数和块等等。每个源文件的这项工作都可以完全独立地完成。如果您有 5000 个源文件，并且有 8 个 CPU，则可以将它们分成八个部分，然后让每个 CPU 开始工作，并将它们的数据结构保留在内存中。完成之后，您可以说“现在我拥有了所有的数据结构，现在可以构建将它们全部链接在一起的东西了”。但是，这仅在所有进程都位于共享内存空间中时才有效。这就是您在 JavaScript 中遇到问题的地方。因为在 JavaScript 中实现并发的唯一方法是使用 Web Workers。Web Workers 的一个关键特征是它们彼此隔离，无法共享内存。它们唯一可以共享的是一种来回传递 JSON 的方式，或者是一个字节数组，但不能共享任何结构化数据。</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>因此，我们可以使用 JavaScript 并行执行所有这些解析，但我们会留下八个孤立的世界，每个世界都只有八分之一的全局视图。为了将所有这些放在一起，我们必须跨越边界进行编组，而这比解析源文件本身所花费的时间还要长。所以您又放弃了一切。这就是并发在其中发挥作用的一种方式。当然，很久以前，摩尔定律就停止为我们提供更快的 CPU。相反，它为我们提供了更多的 CPU。如果您无法利用这一点，您就是在浪费大量的潜在资源。现在，我们可以利用它了。幸运的是，我们拥有一种架构，可以让我们非常轻松地做到这一点。将解析和绑定阶段转变为并发绑定和并发解析非常简单。我不是在开玩笑，这大概只需要 10 行左右的代码，就可以在 goroutine 中运行这些操作。然后在一些地方，我们需要访问共享资源，例如生成唯一序列号的东西。这需要通过互斥锁来保护。完成之后，它就可以快 3 到 4 倍地运行。这绝对是我们所经历的。</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>这是非常强大的 10 行代码。是的，类型检查器的情况稍微复杂一些，因为与解析不同，类型检查并不是独立于每个文件的。类型检查器的整个思想是拥有一个全局程序视图，这样代码就可以从其他文件中导入，并且你可以进行交叉引用。这意味着，当您键入“let x: SomeTypeName”时，该“SomeTypeName”可能来自另一个文件。现在您必须去那里并开始解析那里的内容。你跨越了很多边界。我们认真思考了如何才能做到这一点，因为我们知道，检查阶段是在编译过程中最耗时的步骤。检查占用了 60% 到 70% 的时间。我们提出了一种方案，实际上我们并没有尝试使类型检查器实现完全的并发安全，避免 CPU 同时修改相同的可变数据结构，因为这几乎是不可能的。相反，我们所做的是获取您的程序，然后将其分成几个部分（当前硬编码为四个，但我们可能会更改此值）。这意味着我们会将您的程序分成四份，然后创建四个类型检查器。我们将整个程序都提供给每个类型检查器，但告诉它们只检查分配给它们的那一部分文件。然后，它们就开始独立工作了。它们唯一共享的内容是底层的抽象语法树（AST），它是不可变的。然后，它们构建自己的状态来表示类型。它们检查的大多数类型都位于分配给它们的源文件中。但是，有时它们会跨越边界，并在那里重复一些工作，解析一个类型。但总的来说，这种方法具有很好的可扩展性。通过这种方法，我们可以在消耗大概 20% 更多内存（因为会存在重复的类型）的前提下，额外获得大约 3 倍的性能提升。这是一项非常划算的交易。我们仍然比旧编译器消耗更少的内存，并且现在我们可以快 10 倍了，因为这是一种乘法效应。 如果您从原生代码获得 3 倍的性能提升，并且从并发获得 3 倍的性能提升，那么总体的性能提升就会是 10 倍。这是一个巨大的范式转变。</p>
<p><strong>主持人：</strong></p>
<p>我想展望未来，思考这对于 TypeScript 项目的未来 10 年或 12 年意味着什么。您认为语言特性会发生什么变化？实际上，我一直在倡导减少语言特性，而更加注重稳定性和其他类似的事情。如果没有任何新特性添加，我会非常高兴。我之前被问到关于 Doom 项目的事情，TypeScript 可以添加哪些特性来使其更容易实现？我想说，目前已有的特性就足以运行 Doom 了。显然，TypeScript 已经图灵完备。您是否有一些时刻，因为意识到某些特性会带来巨大的性能开销，所以过去没有实现，而现在这种新的架构可能会在一年后为这些特性打开大门？</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>我认为我最兴奋的是……首先，如果我们在 TypeScript 推出后的两三年就尝试进行这种移植，那么世界，甚至是我们自己是否做好了准备都还不清楚。但是，现在我们已经达到了一定的成熟度。ECMAScript 的发展速度肯定不如当年从 ES5 到 ES6 过渡时那么快，那时我们获得了类、lambda 表达式等等。现在发展速度慢了很多。我们从社区的反馈中也看到，越来越多的人关心可扩展性和性能，而越来越少的人关心花哨的新类型系统特性。</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>我们当然会继续关注 ECMAScript 委员会的工作，并且积极参与其中。对于由此产生的任何新特性，我们肯定会在类型系统中给予适当的处理。我们也可能会设想出新的类型系统特性，但我认为更有趣的是思考一个类型检查器速度快 10 倍所带来的影响。当它与人工智能、智能编程等领域的最新进展结合起来时，我们如何利用这种更快速的信息生成能力？例如，为大型语言模型 (LLM) 提供上下文信息：这些类型实际解析成什么？这个符号是什么符号？它在哪里声明的？因为现在 LLM 只能看到拼写，并不能真正理解其含义。因此，我们可以实时地为它们提供更高保真度的信息。我们还可以实时地检查 AI 的输出，以确保其不仅在语法上正确，而且在语义上也是正确的。如果您打算让这些 AI 生成代码并实际运行它，那就需要这些特性。谁能保证 AI 生成的代码是安全的？保持 AI 诚实的唯一方法是通过确定性的类型检查器或验证器。</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>我认为这开辟了一些非常有趣的新途径，这些途径是我们在以前不可能追求的。我们现在可以开始思考它们。其中一种潜在途径是，未来是否会出现一个 TypeScript 原生的运行时？当然，存在 Deno，它是用 Rust 编写的。或许这项工作与它之间会有一些交叉。您认为未来是否会有一个基于此代码库构建的 TypeScript 优先的运行时？</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>我已经学会了“永远不要说永远不会”。在这个行业以及我所经历的一切中，这句话总是应验。这肯定有可能发生。我想说的是，今天减慢 JavaScript 速度的一些因素（比如主要的运行时 V8 以及 JIT 编译等）有可能在使用原生编译的系统中被消除。还有 JavaScript 的对象模型。比如，您可以随意向对象添加新属性，以及计算属性名称。在 JavaScript 中，对象更像是哈希表，而不是内存插槽中布局的结构体。即使我们有时这样认为，但它们的实际行为并非如此。JavaScript 对数字的处理（比如没有整数，一切都是浮点数）也带来了诸多限制。如果您想要保留完全相同的语义，就无法消除这些限制。您可以设想一种看起来像 TypeScript 但具有不同语义的语言。有些人已经尝试过这样做了。然后您可以为它构建一个原生编译器。但这是否是人们所期望的？这很难说。</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>我不知道这一切会走向何方。我经常希望存在一种魔法粉末，我们可以用它来为 JavaScript 创建一个原生运行时，并使其速度提高一个数量级，就像我们现在所做的那样。但老实说，我认为在可预见的未来，这种情况不太可能发生。</p>
<p><strong>主持人：</strong></p>
<p>您说的很有道理。我是一个充满热情的爱好者，这些都是我一直在思考的问题，请不要介意。我真正想问的最后一个问题是，当我看到工具迁移到 Rust 时，我常常会看到社区出现一些担忧，虽然这可能并不是强烈的反对，但人们担心原先乐于贡献 TypeScript 和 JavaScript 的开发者会因为工具迁移到 Rust 而被抛弃，或者说被强迫学习 Rust。对于 TypeScript 和 Go 来说，也可能存在类似的担忧。我想知道您有什么看法。我实际上认为这从净收益来看是积极的。这些社区中存在着大量的活力。我们已经看到了这些 Rust 工具的成功，这证明了人们愿意走出自己的舒适区，为了他们所关心的事情而学习新的东西。我只是好奇您是否考虑过第三方贡献的问题。TypeScript 已经收到了很多很棒的第三方贡献。</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>当然，同时了解 Go 和 JavaScript 的人肯定比只了解 JavaScript 的人要少。因此，贡献者的人数可能会减少。但话说回来，为编译器做出贡献的人本来就不多。而且他们通常非常感兴趣，并且经常跨足原生环境。我也想说，从 JavaScript 过渡到 Go 实际上对系统来说相当温和。<strong>Go 并不是一种超级复杂，具有大量繁文缛节的语言，而 Rust 则更符合这种描述</strong>。Rust 更像是现代 C++，而不是现代化的 JavaScript。<strong>Go 在某些方面则像是现代化的、原生的 Python JavaScript</strong>。</p>
<p><strong>主持人：</strong></p>
<p>过去，当我编写 Go 代码时，我曾经用 Go 进行了大约两年的专业开发。在一次工程全体会议上，一些工程师抱怨 Go 很平庸。他们对无法在 Go 中<br />
实现某些复杂的东西感到不满。首席技术官制止了他们，并说您必须理解 <strong>Go 的设计目标就是平庸。它并不是要变得花哨，而是要保持简单</strong>。</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>老实说，**它确实很简单，但是其结果却并不平庸。性能提升 10 倍绝对称不上平庸。您可以用它完成伟大的事情。</p>
<p><strong>主持人：</strong></p>
<p>Kubernetes 绝对不是一个平庸的软件项目**。我不得不说，我对这下一个篇章感到非常兴奋。我认为这是一个伟大的举措，而且听起来这是一个经><br />
过深思熟虑的决定。我很高兴你们在各个方面都投入了大量的精力，从第三方贡献到其他每一个要素，都进行了细致的评估。我很高兴你们对这个项<br />
目如此认真。看到这些总是让人感到非常欣慰。我一直非常欣赏这个团队所做出的贡献。 难以置信的是，这个项目已经发展到了如此的程度，并拥>有如此多的功能，而且仍然在蓬勃发展。我们即将见证一个全新的篇章。祝贺您和您的团队！</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>非常感谢。我也可以告诉您，我们所有人都对此感到非常兴奋。这绝对像是给团队打了一针强心剂，并且我认为对于整个社区来说也是如此。我认为这将为 TypeScript 开启又一个精彩的十年，在这十年中将会涌现出许多令人兴奋的事物。我们对此感到无比激动。</p>
<p><strong>主持人：</strong></p>
<p>感谢您加入我们。能够听到这些细节真是太棒了。我认为这些信息对于库作者和 TypeScript 社区的先行者来说都非常有价值。</p>
<p><strong>Anders Hejlsberg：</strong></p>
<p>我很荣幸。感谢您的邀请。</p>
<p><strong>主持人：</strong></p>
<p>如果您喜欢这个视频，也许您也想知道来自 TypeScript 团队的 Jake Bailey 将会在 Squiggle Comp 会议上发表演讲，介绍团队将 TypeScript 移植到 Go 的过程。会议将在 9 月 18 日和 19 日在波士顿举行。感谢您的收看！</p>
<hr />
<blockquote>
<p>BTW，在<a href="https://github.com/microsoft/typescript-go">typescript-go项目</a>的一个名为<a href="https://github.com/microsoft/typescript-go/discussions/411">Why Go的discussion</a>中，<a href="https://github.com/microsoft/typescript-go/discussions/411#discussioncomment-12476218">Anders Hejlsberg做了总结性的陈词</a>，这里也将其翻译成中文，连同上面专访一同供大家参考。</p>
</blockquote>
<p><strong>Anders Hejlsberg：</strong></p>
<p><strong>我们决定移植到 Go，这凸显了我们对务实工程选择的承诺</strong>。我们的重点是实现尽可能最好的结果，而与使用的语言无关。在微软，我们利用多种编程语言，包括 C#、Go、Java、Rust、C++、TypeScript 以及其他语言。每种语言都是根据技术适用性和团队生产力精心选择的。事实上，C# 仍然是微软内部最流行的语言，而且遥遥领先。</p>
<p>TypeScript 编译器迁移到 Go 受到了具体技术要求的驱动，例如需要与现有的基于 JavaScript 的代码库保持结构兼容性，易于进行内存管理，以及能够高效地处理复杂的图处理。在评估了众多语言并制作了多个原型之后（包括 C#），Go 脱颖而出，成为了最优选择，它为树遍历提供了极佳的体验，易于进行内存分配，并且代码结构与现有编译器非常相似，从而简化了维护和兼容性。</p>
<p>在一个全新的项目中，这将会是一个完全不同的对话。但这并非一个全新的项目，而是一个已经投入了 100 人年工作的现有代码库的移植。是的，我们可以从头开始用 C# 重新设计编译器，并且它也能工作。事实上，C# 自己的编译器 Roslyn 就是用 C# 编写的，并且可以自举。但这并不是一次编译器重新设计，而且 <strong>TypeScript 到 Go 的迁移在映射关系上更可自动化，也更加一对一</strong>。我们现有的代码库全部都是函数和数据结构，没有类。符合 Go 语言习惯的代码看起来就像我们现有的代码库，所以移植工作大大简化了。</p>
<p>虽然这个决定非常适合 TypeScript 的具体情况，但这并不会削弱我们在 C# 和 .NET 上的深度和持续投入。微软的大多数服务和产品都严重依赖 C# 和 .NET，因为它们具有无与伦比的生产力、强大的生态系统以及强大的可扩展性。C# 在需要快速、可维护和可扩展的开发场景中表现出色，为关键系统和众多内部和外部微软解决方案提供动力。现代的、跨平台的 .NET 也提供了出色的性能，使其成为构建云服务的理想选择，这些云服务可以在任何操作系统上以及跨多个云提供商无缝运行。 .NET 9 中最近的性能改进进一步证明了我们对这个强大生态系统的持续投入（https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-9/）。</p>
<p>说实话，微软使用 Go 来编写 TypeScript 的编译器在几年前是无法实现或想象的。然而，在过去的几十年里，我们看到了微软对开源软件的坚定和持续的承诺，将开发人员的生产力和社区协作置于一切之上。我们的目标是为开发人员提供最好的工具，不受内部政治或狭隘约束的阻碍。这种为每个特定工作选择合适工具的自由最终惠及整个开发者社区，推动创新、效率和改善结果。而且，你无法反驳 10 倍的性能提升！</p>
<p>没有任何一种语言是完美适用于所有任务的。在微软，我们赞赏编程语言多样性所带来的力量。我们对 C# 和 .NET 的承诺仍然比以往任何时候都更加坚定，我们将不断增强这些技术，为开发人员提供他们现在以及将来成功所需的工具。</p>
<hr />
<p><a href="https://public.zsxq.com/groups/51284458844544">Gopher部落知识星球</a>在2025年将继续致力于打造一个高品质的Go语言学习和交流平台。我们将继续提供优质的Go技术文章首发和阅读体验。并且，2025年将在星球首发“Go陷阱与缺陷”和“Go原理课”专栏！此外，我们还会加强星友之间的交流和互动。欢迎大家踊跃提问，分享心得，讨论技术。我会在第一时间进行解答和交流。我衷心希望Gopher部落可以成为大家学习、进步、交流的港湾。让我相聚在Gopher部落，享受coding的快乐! 欢迎大家踊跃加入！</p>
<p><img src="http://image.tonybai.com/img/tonybai/gopher-tribe-zsxq-small-card.png" alt="img{512x368}" /><br />
<img src="http://image.tonybai.com/img/tonybai/go-programming-from-beginner-to-master-qr.png" alt="img{512x368}" /></p>
<p><img src="http://image.tonybai.com/img/tonybai/go-first-course-banner.png" alt="img{512x368}" /><br />
<img src="http://image.tonybai.com/img/tonybai/imooc-go-column-pgo-with-qr.jpg" 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/03/13/interview-with-anders-hejlsberg/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
