<?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; 编辑器</title>
	<atom:link href="http://tonybai.com/tag/%e7%bc%96%e8%be%91%e5%99%a8/feed/" rel="self" type="application/rss+xml" />
	<link>https://tonybai.com</link>
	<description>一个程序员的心路历程</description>
	<lastBuildDate>Mon, 08 Jun 2026 23:32:23 +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>Go写业务是垃圾？Rust重写是坨屎？聊聊程序员评论区里的那股“煞气”</title>
		<link>https://tonybai.com/2025/09/19/the-tension-in-programmer-comments/</link>
		<comments>https://tonybai.com/2025/09/19/the-tension-in-programmer-comments/#comments</comments>
		<pubDate>Fri, 19 Sep 2025 00:10:06 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[Bug]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Emacs]]></category>
		<category><![CDATA[GC问题]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[go1.24]]></category>
		<category><![CDATA[Gopher]]></category>
		<category><![CDATA[Go语言第一课]]></category>
		<category><![CDATA[MAC]]></category>
		<category><![CDATA[Rust]]></category>
		<category><![CDATA[Rustacean]]></category>
		<category><![CDATA[TonyBai]]></category>
		<category><![CDATA[Vim]]></category>
		<category><![CDATA[WebAssembly]]></category>
		<category><![CDATA[Windows]]></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>
		<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>
		<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=5178</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/09/19/the-tension-in-programmer-comments 大家好，我是Tony Bai。 做公众号/博客这些年，我收到了成千上万条来自程序员朋友的评论。绝大多数都充满了智慧、好奇和善意，正是这些交流，构成了我持续分享的最大动力。但与此同时，我也常常在评论区里，感受到一股强烈的、带有攻击性的无形之气。 比如，当我分享一篇关于Go在业务场景实践的文章时，总会有人跳出来，言简意赅地留下一句：“用Go写业务是不是很垃圾？” 又比如，当社区在探讨用Rust重构某个C++项目时，评论区可能会出现这样的“高论”：“用Rust重写C++代码，就是从一坨屎变成了另一坨屎。” 这些评论，往往脏字当头，不带任何论据，纯粹是情绪的宣泄。我思来想去，觉得用“戾气”或“喷子”来形容，似乎都不够精准。直到有一天，一个词蹦进了我的脑海——“煞气”。 这个词，源于传统文化，意指一种凶戾、非理性、具有破坏性的气场。它精准地捕捉了这类评论的本质：其目的并非交流思想，而是用情绪的冲击波，扼杀讨论，打击分享者的热情。正因如此，我之前公众号的自动精选评论和留言不得不改为手工精选，这不仅增加了工作量，还降低了评论展示的及时性。 今天，这篇文章不旨在批判，而是想和大家一起，深入地聊一聊程序员评论区里的这股“煞气”，尝试理解它从何而来，并探讨作为技术社区的一员，我们该如何面对它，如何保护我们共同的精神家园。 “煞气”的百态图鉴：你一定见过的几种典型“煞评” 这股“煞气”并非铁板一块，它以多种面目出现在我们的视野中，总有一种让你觉得似曾相识： “一言以蔽之”型 这类评论堪称“断言大师”，从不屑于提供论据，仅用一句话便能给一门语言、一个框架甚至一个技术方向盖棺定论。 “Go就是不行。” “WebAssembly没前途。” “微服务就是个坑。” 简洁，有力，不容置疑，仿佛掌握了宇宙的终极真理。 “非黑即白”型（技术圣战） 在他们眼中，技术选型不是基于场景和权衡，而是一场关乎信仰的“圣战”。语言、编辑器、操作系统……万物皆可站队，异端必须被消灭。 “用Rust重写C++就是从一坨屎变成另一坨屎。” “Vim/Emacs之外皆异端！” “还在用Windows/Mac开发？笑死。” “资格论”与“秀优越”型 这类评论善于通过攻击对方的身份、资历或知识储备，来釜底抽薪式地否定其观点，从而建立自己的优越感。 “你连源码都没读过，凭什么评论？” “这东西我十年前就玩过了，没什么新意。” “等你写到百万行代码再来讨论架构吧。” “情绪投射”型 这类评论者，往往将自己在工作中因某项技术受挫而产生的负面情绪，无差别地投射到所有相关的公开讨论中，把评论区当成了情绪的垃圾桶。 “我们项目刚被XXX坑惨了，这玩意儿就是个彻头彻尾的垃圾！” “又在吹这门语言？我刚因为它的GC问题加了三天班！” 这些充满“煞气”的评论，像病毒一样侵蚀着技术社区的讨论氛围，让许多乐于分享的创作者心生寒意，也让许多渴望学习的新人望而却步。 溯源“煞气”：它们究竟从何而来？ 要应对“煞气”，首先要理解它的来源。它并非简单的“素质问题”，背后往往有更深层次的、属于程序员群体的心理动因： 高认知负荷与挫败感： 软件开发本质上是一项与复杂性搏斗的高难度、高挫败感的工作。代码不工作是常态，被需求反复折磨是日常。长期累积的压力和挫败感，需要一个宣泄的出口，而匿名的网络评论区便成了最廉价的选择。 强身份认同与技术部落主义： 许多程序员倾向于将自我价值与所掌握的技术栈深度绑定。“我是Gopher”、“我是Rustacean”，这种身份认同感带来了归属感，但也催生了“部落主义”。攻击对立的技术，本质上是在捍卫自我身份和所属部落的“荣耀”。 对“最优解”的执念与抽象能力的差异： 我们的工作是与逻辑打交道，追求严谨和正确，这使得许多程序员潜意识里相信存在一个放之四海而皆准的“最优解”。这种思维惯性，导致在面对需要权衡（Trade-off）的工程问题时，容易陷入“非黑即白”的二元对立，无法容忍不同场景下的不同选择。 知识的诅咒： 一些资深开发者，已经忘记了自己初学时期的困惑和挣扎。他们对自己领域内“显而易见”的知识缺乏同理心，容易将新手的提问或不成熟的观点视为“愚蠢”，并报以轻蔑或不耐烦。 网络匿名性的放大效应： 这是所有网络社区的通病。脱离了现实世界的社交约束，人们更容易释放出内心的攻击性。 化解“煞气”：我们每个人的社区修行 面对弥漫的“煞气”，无论是内容创作者还是普通读者，我们每个人都身处其中，既可能是受害者，也可能在不经意间成为助推者。与其抱怨环境，不如从自身做起，共同参与到社区的净化与建设中来。 给所有社区参与者的“修行建议”： 评论前，区分“观点”与“情绪”： 在敲下键盘前，花一秒钟审视内心：我即将表达的，是基于逻辑和事实的技术观点，还是仅仅是想吐槽一下今天遇到的某个Bug或者糟糕的心情？有意识地分离这两者，是理性讨论的第一步。 拥抱“建设性批评”的艺术： 如果你不同意某个观点，这非常正常，甚至是技术进步的源泉。但请尝试用建设性的方式来表达： 提供论据： “我认为这个方案有风险，因为在XX场景下，它可能会导致YY问题。” [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2025/the-tension-in-programmer-comments-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/09/19/the-tension-in-programmer-comments">本文永久链接</a> &#8211; https://tonybai.com/2025/09/19/the-tension-in-programmer-comments</p>
<p>大家好，我是Tony Bai。</p>
<p>做公众号/博客这些年，我收到了成千上万条来自程序员朋友的评论。绝大多数都充满了智慧、好奇和善意，正是这些交流，构成了我持续分享的最大动力。但与此同时，我也常常在评论区里，感受到一股强烈的、带有攻击性的无形之气。</p>
<p>比如，当我分享一篇关于Go在业务场景实践的文章时，总会有人跳出来，言简意赅地留下一句：“用Go写业务是不是很垃圾？”</p>
<p>又比如，当社区在探讨用Rust重构某个C++项目时，评论区可能会出现这样的“高论”：“用Rust重写C++代码，就是从一坨屎变成了另一坨屎。”</p>
<p>这些评论，往往脏字当头，不带任何论据，纯粹是情绪的宣泄。我思来想去，觉得用“戾气”或“喷子”来形容，似乎都不够精准。直到有一天，一个词蹦进了我的脑海——<strong>“煞气”</strong>。</p>
<p>这个词，源于传统文化，意指一种凶戾、非理性、具有破坏性的气场。它精准地捕捉了这类评论的本质：其目的并非交流思想，而是用情绪的冲击波，扼杀讨论，打击分享者的热情。正因如此，我之前公众号的自动精选评论和留言不得不改为手工精选，这不仅增加了工作量，还降低了评论展示的及时性。</p>
<p>今天，这篇文章不旨在批判，而是想和大家一起，<strong>深入地聊一聊程序员评论区里的这股“煞气”，尝试理解它从何而来，并探讨作为技术社区的一员，我们该如何面对它，如何保护我们共同的精神家园。</strong></p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/paid/go-micro-column-2025-pr.png" alt="" /></p>
<h2>“煞气”的百态图鉴：你一定见过的几种典型“煞评”</h2>
<p>这股“煞气”并非铁板一块，它以多种面目出现在我们的视野中，总有一种让你觉得似曾相识：</p>
<ul>
<li>
<p><strong>“一言以蔽之”型</strong><br />
这类评论堪称“断言大师”，从不屑于提供论据，仅用一句话便能给一门语言、一个框架甚至一个技术方向盖棺定论。</p>
<ul>
<li><em>“Go就是不行。”</em></li>
<li><em>“WebAssembly没前途。”</em></li>
<li><em>“微服务就是个坑。”</em><br />
简洁，有力，不容置疑，仿佛掌握了宇宙的终极真理。</li>
</ul>
</li>
<li>
<p><strong>“非黑即白”型（技术圣战）</strong><br />
在他们眼中，技术选型不是基于场景和权衡，而是一场关乎信仰的“圣战”。语言、编辑器、操作系统……万物皆可站队，异端必须被消灭。</p>
<ul>
<li><em>“用Rust重写C++就是从一坨屎变成另一坨屎。”</em></li>
<li><em>“Vim/Emacs之外皆异端！”</em></li>
<li><em>“还在用Windows/Mac开发？笑死。”</em></li>
</ul>
</li>
<li>
<p><strong>“资格论”与“秀优越”型</strong><br />
这类评论善于通过攻击对方的身份、资历或知识储备，来釜底抽薪式地否定其观点，从而建立自己的优越感。</p>
<ul>
<li><em>“你连源码都没读过，凭什么评论？”</em></li>
<li><em>“这东西我十年前就玩过了，没什么新意。”</em></li>
<li><em>“等你写到百万行代码再来讨论架构吧。”</em></li>
</ul>
</li>
<li>
<p><strong>“情绪投射”型</strong><br />
这类评论者，往往将自己在工作中因某项技术受挫而产生的负面情绪，无差别地投射到所有相关的公开讨论中，把评论区当成了情绪的垃圾桶。</p>
<ul>
<li><em>“我们项目刚被XXX坑惨了，这玩意儿就是个彻头彻尾的垃圾！”</em></li>
<li><em>“又在吹这门语言？我刚因为它的GC问题加了三天班！”</em></li>
</ul>
</li>
</ul>
<p>这些充满“煞气”的评论，像病毒一样侵蚀着技术社区的讨论氛围，让许多乐于分享的创作者心生寒意，也让许多渴望学习的新人望而却步。</p>
<h2>溯源“煞气”：它们究竟从何而来？</h2>
<p>要应对“煞气”，首先要理解它的来源。它并非简单的“素质问题”，背后往往有更深层次的、属于程序员群体的心理动因：</p>
<ol>
<li><strong>高认知负荷与挫败感：</strong> 软件开发本质上是一项与复杂性搏斗的高难度、高挫败感的工作。代码不工作是常态，被需求反复折磨是日常。长期累积的压力和挫败感，需要一个宣泄的出口，而匿名的网络评论区便成了最廉价的选择。</li>
<li><strong>强身份认同与技术部落主义：</strong> 许多程序员倾向于将自我价值与所掌握的技术栈深度绑定。“我是Gopher”、“我是Rustacean”，这种身份认同感带来了归属感，但也催生了“部落主义”。攻击对立的技术，本质上是在捍卫自我身份和所属部落的“荣耀”。</li>
<li><strong>对“最优解”的执念与抽象能力的差异：</strong> 我们的工作是与逻辑打交道，追求严谨和正确，这使得许多程序员潜意识里相信存在一个放之四海而皆准的“最优解”。这种思维惯性，导致在面对需要权衡（Trade-off）的工程问题时，容易陷入“非黑即白”的二元对立，无法容忍不同场景下的不同选择。</li>
<li><strong>知识的诅咒：</strong> 一些资深开发者，已经忘记了自己初学时期的困惑和挣扎。他们对自己领域内“显而易见”的知识缺乏同理心，容易将新手的提问或不成熟的观点视为“愚蠢”，并报以轻蔑或不耐烦。</li>
<li><strong>网络匿名性的放大效应：</strong> 这是所有网络社区的通病。脱离了现实世界的社交约束，人们更容易释放出内心的攻击性。</li>
</ol>
<h2>化解“煞气”：我们每个人的社区修行</h2>
<p>面对弥漫的“煞气”，无论是内容创作者还是普通读者，我们每个人都身处其中，既可能是受害者，也可能在不经意间成为助推者。与其抱怨环境，不如从自身做起，共同参与到社区的净化与建设中来。</p>
<p><strong>给所有社区参与者的“修行建议”：</strong></p>
<ol>
<li><strong>评论前，区分“观点”与“情绪”：</strong> 在敲下键盘前，花一秒钟审视内心：我即将表达的，是基于逻辑和事实的技术观点，还是仅仅是想吐槽一下今天遇到的某个Bug或者糟糕的心情？有意识地分离这两者，是理性讨论的第一步。</li>
<li><strong>拥抱“建设性批评”的艺术：</strong> 如果你不同意某个观点，这非常正常，甚至是技术进步的源泉。但请尝试用建设性的方式来表达：
<ul>
<li><strong>提供论据：</strong> “我认为这个方案有风险，因为在XX场景下，它可能会导致YY问题。”</li>
<li><strong>提供替代方案：</strong> “相比A方案，我更推荐B方案，因为B在处理XX方面更有优势。”</li>
<li><strong>补充上下文：</strong> “这个观点在小型项目中可能适用，但在大规模分布式系统中，我们需要额外考虑……”<br />
这样的评论，远比一句简单的“你这是垃圾”有价值千万倍。</li>
</ul>
</li>
<li><strong>常怀谦逊与同理心：</strong> 技术世界浩瀚无垠，我们每个人都只是其中渺小的一粟。承认自己知识的局限性，尊重不同技术在不同场景下的存在价值。我们今天所不屑的，可能正是我们昨天所困惑的；我们今天所熟稔的，可能是别人明天将要探索的新大陆。多一份同理心，少一份优越感。</li>
</ol>
<h2>小结：化“煞气”为“祥和之气”，共建更有价值的技术社区</h2>
<p>回到开头的那些评论。Go写业务当然不是垃圾，Rust重写C++也绝非原地踏步。每一种技术选择背后，都有其复杂的工程背景和权衡考量。一个健康的技术社区，应该是一个能够容纳并理性探讨这些权衡的地方。</p>
<p>我们探讨“程序员的‘煞气’”，目标不是消灭所有反对的声音，健康的质疑和辩论是技术进步的基石。我们的目标，是希望将那些无意义的、纯粹消耗热情的情绪宣泄，转化为能够推动我们共同进步的思想碰撞。</p>
<p>这需要我们每一位社区参与者的共同努力：分享者多一份对人性的理解和对经验的珍视，评论者多一份理性和建设性的态度。</p>
<p>愿我们都能成为驱散“煞气”的光，让技术社区的每一次讨论，都离智慧更近一步。</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/09/19/the-tension-in-programmer-comments/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>
		<item>
		<title>Anders Hejlsberg谈TypeScript编译器向Go移植的实践与规划</title>
		<link>https://tonybai.com/2025/03/12/typescript-native-port-to-go/</link>
		<comments>https://tonybai.com/2025/03/12/typescript-native-port-to-go/#comments</comments>
		<pubDate>Tue, 11 Mar 2025 22:39:14 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[AndersHejlsberg]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Compiler]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[GC]]></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[内存管理]]></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=4501</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/03/12/typescript-native-port-to-go TypeScript、C#语言、Delphi语言之父Anders Hejlsberg今日在Microsoft开发者博客宣布重大消息，TypeScript编译器以及工具链将移植到Go语言，性能提升高达10倍！这究竟是怎么回事？为什么要用Go？对开发者有什么影响？本文将为你深度解读。 TypeScript迎来史诗级更新，性能提升10倍！ 就在今天，TypeScript社区迎来了一颗重磅炸弹！微软技术院士、TypeScript首席架构师、C#、Delphi和Turbo Pascal的最初设计者——Anders Hejlsberg，亲自在微软开发者博客上宣布，TypeScript团队正在进行一项激动人心的计划：将TypeScript编译器和相关工具链移植到Go语言！ 这一举动旨在解决TypeScript在大型代码库中性能瓶颈的问题，为开发者带来更流畅、更高效的开发体验。根据官方公布的数据，新的原生实现将带来以下惊人的改进： 编辑器启动的项目加载速度提升8倍！ 大多数构建时间缩短10倍！ 内存使用量大幅减少！ 这意味着，开发者将告别漫长的加载和等待，享受“秒开”项目的快感，获得更流畅的代码编辑、智能提示、代码导航等体验。 实测数据说话，性能提升肉眼可见！ 为了证明新版编译器的强大性能，TypeScript团队选取了GitHub上多个不同规模的热门TypeScript项目进行测试，以下是测试结果： 从数据中我们可以清晰地看到，无论是大型项目如 VS Code，还是小型库如 rxjs，新版编译器都实现了 10 倍左右的性能提升！ Anders Hejlsberg 表示，这仅仅是开始，随着开发的深入，性能还将进一步优化。 为什么要移植到Go？ 面对这一重大变革，很多开发者可能会疑惑：为什么选择Go语言？C#或者Rust不香吗？ 对此，Anders Hejlsberg和TypeScript团队在TypeScript GitHub仓库的讨论区进行了解释，主要原因有以下几点： 代码结构相似性： TypeScript 现有代码库采用函数式编程风格，很少使用类。而Go语言也以函数和数据结构为中心，与现有代码结构高度相似，这使得移植工作更加容易。 内存管理：Go语言提供自动垃圾回收（GC），无需开发者手动管理内存，这大大简化了移植过程，降低了代码复杂度。同时，Go的GC对TypeScript编译器这类批处理任务影响很小。 内存布局控制： Go语言允许对内存布局和分配进行精细控制，这对于优化性能至关重要。 图处理能力： TypeScript编译器涉及大量的树遍历和多态节点处理，Go语言在这方面表现出色。 Anders Hejlsberg 强调，这是一次“移植”而非“重写”，目标是尽可能保留现有代码库的结构和语义，确保兼容性。Go语言的特性与TypeScript现有代码库的契合度最高，是“阻力最小”的路径。 针对社区关心的为什么不选择C#，Anders Hejlsberg也做了专门回应： Go是能同时做到原生性和自动垃圾收集的最低层级语言。 C#是字节码优先的，虽然也有AOT编译，但有平台限制，且没有像Go一样经过长时间的生产环境验证。 C#是重OOP范式的，TypeScript的JS代码库是高度函数式的。 版本路线图 TypeScript团队公布了明确的版本路线图： 当前版本为TypeScript 5.8，即将发布TypeScript 5.9。 基于JavaScript的代码库将继续开发到 6.x 系列，TypeScript 6.0 [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/typescript-native-port-to-go-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/03/12/typescript-native-port-to-go">本文永久链接</a> &#8211; https://tonybai.com/2025/03/12/typescript-native-port-to-go</p>
<blockquote>
<p>TypeScript、C#语言、Delphi语言之父<a href="https://github.com/ahejlsberg">Anders Hejlsberg</a>今日在Microsoft开发者博客宣布重大消息，<a href="https://devblogs.microsoft.com/typescript/typescript-native-port/">TypeScript编译器以及工具链将移植到Go语言</a>，性能提升高达10倍！这究竟是怎么回事？为什么要用Go？对开发者有什么影响？本文将为你深度解读。</p>
</blockquote>
<h2>TypeScript迎来史诗级更新，性能提升10倍！</h2>
<p>就在今天，TypeScript社区迎来了一颗重磅炸弹！微软技术院士、TypeScript首席架构师、C#、Delphi和Turbo Pascal的最初设计者——<strong>Anders Hejlsberg</strong>，亲自在微软开发者博客上宣布，TypeScript团队正在进行一项激动人心的计划：<strong>将TypeScript编译器和相关工具链移植到Go语言！</strong></p>
<p>这一举动旨在解决TypeScript在大型代码库中性能瓶颈的问题，为开发者带来更流畅、更高效的开发体验。根据官方公布的数据，新的原生实现将带来以下惊人的改进：</p>
<ul>
<li><strong>编辑器启动的项目加载速度提升8倍！</strong></li>
<li><strong>大多数构建时间缩短10倍！</strong></li>
<li><strong>内存使用量大幅减少！</strong></li>
</ul>
<p>这意味着，开发者将告别漫长的加载和等待，享受“秒开”项目的快感，获得更流畅的代码编辑、智能提示、代码导航等体验。</p>
<h2>实测数据说话，性能提升肉眼可见！</h2>
<p>为了证明新版编译器的强大性能，TypeScript团队选取了GitHub上多个不同规模的热门TypeScript项目进行测试，以下是测试结果：</p>
<p><img src="https://tonybai.com/wp-content/uploads/typescript-native-port-to-go-3.png" alt="" /></p>
<p>从数据中我们可以清晰地看到，无论是大型项目如 VS Code，还是小型库如 rxjs，新版编译器都实现了 <strong>10 倍左右的性能提升</strong>！</p>
<p><img src="https://tonybai.com/wp-content/uploads/typescript-native-port-to-go-2.png" alt="" /></p>
<p>Anders Hejlsberg 表示，这仅仅是开始，随着开发的深入，性能还将进一步优化。</p>
<h2>为什么要移植到Go？</h2>
<p>面对这一重大变革，很多开发者可能会疑惑：为什么选择Go语言？C#或者Rust不香吗？</p>
<p>对此，Anders Hejlsberg和TypeScript团队在<a href="https://github.com/microsoft/typescript-go/discussions/411">TypeScript GitHub仓库的讨论区</a>进行了解释，主要原因有以下几点：</p>
<ol>
<li><strong>代码结构相似性：</strong> TypeScript 现有代码库采用函数式编程风格，很少使用类。而Go语言也以函数和数据结构为中心，与现有代码结构高度相似，这使得移植工作更加容易。</li>
<li><strong>内存管理：</strong>Go语言提供自动垃圾回收（GC），无需开发者手动管理内存，这大大简化了移植过程，降低了代码复杂度。同时，Go的GC对TypeScript编译器这类批处理任务影响很小。</li>
<li><strong>内存布局控制：</strong> Go语言允许对内存布局和分配进行精细控制，这对于优化性能至关重要。</li>
<li><strong>图处理能力：</strong> TypeScript编译器涉及大量的树遍历和多态节点处理，Go语言在这方面表现出色。</li>
</ol>
<p>Anders Hejlsberg 强调，这是一次“移植”而非“重写”，目标是尽可能保留现有代码库的结构和语义，确保兼容性。Go语言的特性与TypeScript现有代码库的契合度最高，是“阻力最小”的路径。</p>
<p><strong>针对社区关心的为什么不选择C#，Anders Hejlsberg也做了专门回应：</strong></p>
<ul>
<li>Go是能同时做到原生性和自动垃圾收集的最低层级语言。</li>
<li>C#是字节码优先的，虽然也有AOT编译，但有平台限制，且没有像Go一样经过长时间的生产环境验证。</li>
<li>C#是重OOP范式的，TypeScript的JS代码库是高度函数式的。</li>
</ul>
<h2>版本路线图</h2>
<p>TypeScript团队公布了明确的版本路线图：</p>
<ul>
<li>当前版本为TypeScript 5.8，即将发布TypeScript 5.9。</li>
<li>基于JavaScript的代码库将继续开发到 6.x 系列，TypeScript 6.0 将引入一些弃用和破坏性更改，为原生代码库做准备。</li>
<li>当原生代码库达到与当前TypeScript相当的功能时，将发布<strong>TypeScript 7.0</strong>。</li>
<li>为了保持清晰，TS团队将分别称之为TypeScript 6 (JS) 和 TypeScript 7 (native)。</li>
<li>TypeScript 6 (JS) 将持续维护，直到 TypeScript 7+ 达到足够的成熟度和采用率。</li>
<li>内部讨论或代码注释中可能会出现“Strada” (TypeScript 原始代号)和“Corsa” (此次工作的代号)。</li>
</ul>
<p>TypeScript团队预计在2025年中期发布一个能够进行命令行类型检查的原生tsc实现，并在年底发布一个功能完整的项目构建和语言服务解决方案。</p>
<h2>开发者可以做什么？</h2>
<ul>
<li><strong>尝鲜体验：</strong> 你现在就可以从<a href="https://github.com/microsoft/typescript-go">typescript-go仓库</a> 构建和运行Go语言编写的代码，体验新版编译器的强大性能。</li>
<li><strong>关注动态：</strong> 关注TypeScript团队的博客和GitHub仓库，获取最新进展。</li>
<li><strong>参与讨论：</strong> 参与<a href="https://discord.gg/typescript">TypeScript Community Discord</a> 的 AMA 活动（太平洋时间 3 月 13 日上午 10 点 | UTC 时间下午 5 点），与 TypeScript 团队交流。</li>
</ul>
<h2>展望未来</h2>
<p>10倍的性能提升，将为TypeScript和JavaScript开发体验带来巨大飞跃。曾经遥不可及的功能，如今触手可及。这不仅意味着更快的编译速度和更流畅的开发体验，还将为AI驱动的新一代开发工具奠定基础。</p>
<p>TypeScript的这次重大变革，再次证明了微软对开发者社区的承诺，以及对技术创新的不懈追求。让我们一起期待TypeScript的未来，迎接更高效、更智能的开发时代！</p>
<h2>参考资料</h2>
<ul>
<li><a href="https://devblogs.microsoft.com/typescript/typescript-native-port/">A 10x Faster TypeScript</a> &#8211; https://devblogs.microsoft.com/typescript/typescript-native-port/</li>
<li><a href="https://github.com/microsoft/typescript-go/discussions/411">discussions: Why Go? </a> &#8211; https://github.com/microsoft/typescript-go/discussions/411</li>
<li><a href="https://www.youtube.com/watch?v=10qowKUW82U">TypeScript is being ported to Go | interview with Anders Hejlsberg</a> &#8211; https://www.youtube.com/watch?v=10qowKUW82U</li>
</ul>
<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/12/typescript-native-port-to-go/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Go，12周年</title>
		<link>https://tonybai.com/2021/11/11/go-opensource-12-years/</link>
		<comments>https://tonybai.com/2021/11/11/go-opensource-12-years/#comments</comments>
		<pubDate>Thu, 11 Nov 2021 12:59:09 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[2022]]></category>
		<category><![CDATA[ARM65]]></category>
		<category><![CDATA[DAP]]></category>
		<category><![CDATA[delve]]></category>
		<category><![CDATA[filesystem]]></category>
		<category><![CDATA[fuzzing]]></category>
		<category><![CDATA[generics]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[go.dev]]></category>
		<category><![CDATA[go1.16]]></category>
		<category><![CDATA[go1.17]]></category>
		<category><![CDATA[go1.18]]></category>
		<category><![CDATA[go1.19]]></category>
		<category><![CDATA[GoDay]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[gomodule]]></category>
		<category><![CDATA[GopherCon]]></category>
		<category><![CDATA[GopherCon2021]]></category>
		<category><![CDATA[gopls]]></category>
		<category><![CDATA[IanLanceTaylor]]></category>
		<category><![CDATA[macos]]></category>
		<category><![CDATA[Module]]></category>
		<category><![CDATA[RussCox]]></category>
		<category><![CDATA[SBOM]]></category>
		<category><![CDATA[typeparameter]]></category>
		<category><![CDATA[vscode]]></category>
		<category><![CDATA[vscode-go]]></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=3331</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2021/11/11/go-opensource-12-years 2009年11月10日，Go语言正式对外发布并开源。如今，距那一历史时刻已经过去12年了。今早Go核心团队技术负责人Russ Cox在Go官博撰文庆祝Go开源12周年，他回顾了这一年来发布的Go 1.16与Go 1.17版本给Go与Go社区带来的变化，粗略总结了Go核心团队的重点工作，并展望了2022年将发布的Go 1.18和Go 1.19版本。这里对Russ Cox的文章做了简单翻译，供大家参考。 回顾这一年 今天我们庆祝Go语言开源的12岁生日。今年我们经历了多事的一年，明年也有很多值得期待的事情。 与去年庆祝Go 11岁生日的博文相比，这篇博客最明显的变化是它位于我们在go.dev上的新家，这是将我们所有的Go网站整合成一个统一的网站的一部分。整合的另一部分是用pkg.go.dev取代godoc.org。 今年2月，Go 1.16版本增加了对macOS ARM64的支持，增加了文件系统接口和嵌入文件特性，并使得go module构建模式成为默认启用的机制，同时还进行了一系列的改进和优化。 今年8月，Go 1.17版本增加了对Windows ARM64的支持，使TLS密码套件的决策更加简单和安全，引入了修剪模块图，使module在大型项目中更加有效，并增加了新的、更易读的构建约束语法(译注：go:build)。在系统内部，Go 1.17还为x86-64上的Go函数切换到了基于寄存器的调用约定，使依赖CPU的计算密集型的应用程序的性能提高了5-15%。 在这一年中，我们发布了许多新的教程，比如：Go语言数据库操作指南、module开发指南和Go module参考手册。其中一个亮点是新的教程“用Go和Gin开发RESTful API”，该教程也可以通过Google Cloud Shell以互动的形式获得。 我们在IDE方面一直很忙，我们在VS Code Go中默认启用了gopls，并对gopls和VS Code Go进行了无数次的改进，包括由Delve提供的强大的调试体验。 我们还推出了Go Fuzzing test公测版，并正式提议在Go中加入泛型，现在这两项都有望在Go 1.18中实现。 为了继续适应”虚拟优先(virtual-first)”，Go团队在Google Open Source Live上举办了我们的第二个年度Go day，你可以在YouTube上观看这些讲座。 Ian Lance Taylor的“在Go中使用泛型”，介绍了泛型以及如何有效地使用它们。 “现代企业应用”，由Steve Francia主讲，展示了Go如何在企业现代化中发挥作用。 Suzy Mueller的i“用Go编辑器构建更好的项目”，展示了VS Code Go的集成工具如何帮助你浏览代码、调试测试等。 美国运通公司的杰出工程师Benjamin Cane的“从概念验证到生产”，解释了美国运通公司如何在其支付和奖励平台中使用Go。 向前迈进 我们对Go的第13年的发展感到非常兴奋。下个月，我们将在GopherCon 2021上举办两场讲座，同时还有许多来自Go社区的天才演讲者。请免费注册，并在你的日历上做个记号。 [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/go-opensource-12-years-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2021/11/11/go-opensource-12-years">本文永久链接</a> &#8211; https://tonybai.com/2021/11/11/go-opensource-12-years</p>
<p>2009年11月10日，Go语言正式对外发布并开源。如今，距那一历史时刻已经过去12年了。今早Go核心团队技术负责人<a href="https://go.dev/blog/12years">Russ Cox在Go官博撰文庆祝Go开源12周年</a>，他回顾了这一年来发布的Go 1.16与Go 1.17版本给Go与Go社区带来的变化，粗略总结了Go核心团队的重点工作，并展望了2022年将发布的Go 1.18和Go 1.19版本。这里对Russ Cox的文章做了简单翻译，供大家参考。</p>
<hr />
<h3>回顾这一年</h3>
<p>今天我们庆祝Go语言开源的12岁生日。今年我们经历了多事的一年，明年也有很多值得期待的事情。</p>
<p>与去年庆祝<a href="https://tonybai.com/2020/11/11/go-opensource-11-years/">Go 11岁生日的博文</a>相比，这篇博客最明显的变化是它位于我们<a href="https://go.dev/blog/tidy-web">在go.dev上的新家</a>，这是将我们所有的Go网站整合成一个统一的网站的一部分。整合的另一部分是<a href="https://go.dev/blog/godoc.org-redirect">用pkg.go.dev取代godoc.org</a>。</p>
<p>今年2月，<a href="https://mp.weixin.qq.com/s/UPNn4G_m0zfvJgWxEVl_Tw">Go 1.16版本</a>增加了<a href="https://go.dev/blog/blog/ports">对macOS ARM64的支持</a>，增加了<a href="https://mp.weixin.qq.com/s/_pUtGQSl_oSRnmmfROJ6ZQ">文件系统接口</a>和<a href="https://mp.weixin.qq.com/s/UPNn4G_m0zfvJgWxEVl_Tw">嵌入文件特性</a>，并使得go module构建模式成为默认启用的机制，同时还进行了一系列的改进和优化。</p>
<p>今年8月，<a href="https://mp.weixin.qq.com/s/y_pC6GYeZnKuHG8ycNy6rg">Go 1.17版本</a>增加了对Windows ARM64的支持，<a href="https://go.dev/blog/tls-cipher-suites">使TLS密码套件的决策更加简单和安全</a>，引入了<a href="https://mp.weixin.qq.com/s/Fer90nattWxXDWDC1VV55w">修剪模块图</a>，使module在大型项目中更加有效，并<a href="https://mp.weixin.qq.com/s/AkJoXLlpSmw5vMZDpXoq5w">增加了新的、更易读的构建约束语法(译注：go:build)</a>。在系统内部，Go 1.17还为<a href="https://mp.weixin.qq.com/s/AkJoXLlpSmw5vMZDpXoq5w">x86-64上的Go函数切换到了基于寄存器的调用约定</a>，使依赖CPU的计算密集型的应用程序的性能提高了5-15%。</p>
<p>在这一年中，<a href="https://golang.google.cn/doc/tutorial/">我们发布了许多新的教程</a>，比如：<a href="https://golang.google.cn/doc/database/">Go语言数据库操作指南</a>、<a href="https://golang.google.cn/doc/#developing-modules">module开发指南</a>和<a href="https://golang.google.cn/ref/mod">Go module参考手册</a>。其中一个亮点是新的教程<a href="https://golang.google.cn/doc/tutorial/web-service-gin">“用Go和Gin开发RESTful API”</a>，该教程也可以<a href="https://golang.org/s/cloud-shell-web-tutorial">通过Google Cloud Shell以互动的形式获得</a>。</p>
<p>我们在IDE方面一直很忙，我们在<a href="https://go.dev/blog/gopls-vscode-go">VS Code Go中默认启用了gopls</a>，并对gopls和VS Code Go进行了无数次的改进，包括<a href="https://github.com/golang/vscode-go/blob/master/docs/debugging.md">由Delve提供的强大的调试体验</a>。</p>
<p>我们还推出了<a href="https://go.dev/blog/fuzz-beta">Go Fuzzing test公测版</a>，并<a href="https://mp.weixin.qq.com/s/SMT40557JgQ9FjUkswznlA">正式提议在Go中加入泛型</a>，现在这两项都有望在Go 1.18中实现。</p>
<p>为了继续适应”虚拟优先(virtual-first)”，<a href="https://opensourcelive.withgoogle.com/events/go-day-2021">Go团队在Google Open Source Live上举办了我们的第二个年度Go day</a>，你可以在YouTube上观看这些讲座。</p>
<ul>
<li>Ian Lance Taylor的<a href="https://mp.weixin.qq.com/s/ur1eiZl4PKbF1PqELAdfKg">“在Go中使用泛型”</a>，介绍了泛型以及如何有效地使用它们。</li>
<li><a href="https://www.youtube.com/watch?v=5fgG1qZaV4w">“现代企业应用”</a>，由Steve Francia主讲，展示了Go如何在企业现代化中发挥作用。</li>
<li>Suzy Mueller的i<a href="https://www.youtube.com/watch?v=jMyzsp2E_0U">“用Go编辑器构建更好的项目”</a>，展示了VS Code Go的集成工具如何帮助你浏览代码、调试测试等。</li>
<li>美国运通公司的杰出工程师Benjamin Cane的<a href="https://www.youtube.com/watch?v=e7PtBOsTpXE">“从概念验证到生产”</a>，解释了美国运通公司如何在其支付和奖励平台中使用Go。</li>
</ul>
<h3>向前迈进</h3>
<p>我们对Go的第13年的发展感到非常兴奋。下个月，我们将在<a href="https://www.gophercon.com/">GopherCon 2021</a>上举办两场讲座，同时<a href="https://www.gophercon.com/agenda">还有许多来自Go社区的天才演讲者</a>。请免费注册，并在你的日历上做个记号。</p>
<ul>
<li>“<a href="https://www.gophercon.com/agenda/session/593015">为什么和如何使用Go泛型</a>“，由Robert Griesemer和Ian Lance Taylor主讲，他们领导了这项新功能的设计和实施。 12月8日，上午11:00（美国东部）。</li>
<li><a href="https://www.gophercon.com/agenda/session/593029">“使用调试适配器协议（DAP）调试Go代码”</a>，作者Suzy Mueller，展示如何使用VS Code Go的高级调试功能与Delve。<br />
12月9日，下午3:20（美国东部时间）。</li>
</ul>
<p>明年2月，Go 1.18版本将把<a href="https://mp.weixin.qq.com/s/AkJoXLlpSmw5vMZDpXoq5w">新的基于寄存器的调用约定</a>扩展到非x86架构，并带来巨大的性能改进。它将包括新的Go fuzzing test支持。这将是第一个包括对泛型支持的版本。</p>
<p>泛型将是我们2022年的重点之一。<a href="https://mp.weixin.qq.com/s/_4p1wyo3eKEaCU_9GNdkLA">Go 1.18中的初始版本</a>只是一个开始。我们需要花时间使用泛型，了解哪些是有效的，哪些是无效的，这样我们才能写出最佳实践，并决定哪些应该被添加到标准库和其他库中。我们期望Go 1.19（预计在2022年8月）及以后的版本将进一步完善泛型的设计和实现，以及将其进一步整合到整个Go体验中。</p>
<p>2022年的另一个重点是（Go包的）供应链安全。我们多年来一直在<a href="https://research.swtch.com/deps">讨论依赖性的问题</a>。Go module的设计提供了<a href="https://research.swtch.com/vgo-repro">可重复、可验证、可核实的构建</a>，但仍有更多工作要做。从Go 1.18开始，go命令将在二进制文件中嵌入更多关于其构建配置的信息，这既是为了使可重复性更容易，也是为了帮助那些需要为Go二进制文件生成<a href="https://en.wikipedia.org/wiki/Software_bill_of_materials">软件材料清单(Software Bill of Materials, SBOM)</a>的项目。我们也已经开始了<a href="https://pkg.go.dev/golang.org/x/vuln">Go漏洞数据库</a>和相关工具的工作，以报告程序依赖中的漏洞。我们在这项工作中的目标之一是大幅提高这种工具的信噪比：如果一个程序不使用有漏洞的函数，我们就不会报告。在2022年期间，我们计划将其作为一个独立的工具，并将其添加到现有的工具中，包括gopls和VS Code Go，以及pkg.go.dev中。还有更多工作要做，以改善Go的供应链安全态势的其他方面。请继续关注细节。</p>
<p>总的来说，我们预计2022年对Go来说也将是多事的一年，我们将继续提供你所期望的及时发布和改进。</p>
<h3>感谢您!</h3>
<p>Go不仅仅是我们谷歌的Go团队的事情。感谢你们帮助Go取得了成功，并加入我们的冒险。我们希望你们都能保持安全，并祝你们一切顺利。</p>
<hr />
<p><a href="https://mp.weixin.qq.com/s/jUqAL7hf2GmMun64BJufEA">“Gopher部落”知识星球</a>正式转正（从试运营星球变成了正式星球）！“gopher部落”旨在打造一个精品Go学习和进阶社群！高品质首发Go技术文章，“三天”首发阅读权，每年两期Go语言发展现状分析，每天提前1小时阅读到新鲜的Gopher日报，网课、技术专栏、图书内容前瞻，六小时内必答保证等满足你关于Go语言生态的所有需求！部落目前虽小，但持续力很强，欢迎大家加入！</p>
<p><img src="http://image.tonybai.com/img/tonybai/gopher-tribe-zsxq-small-card.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}" /><br />
<img src="http://image.tonybai.com/img/tonybai/imooc-k8s-practice-with-qr.jpg" alt="img{512x368}" /></p>
<p><a href="https://tonybai.com/">我爱发短信</a>：企业级短信平台定制开发专家 https://tonybai.com/。smspush : 可部署在企业内部的定制化短信平台，三网覆盖，不惧大并发接入，可定制扩展； 短信内容你来定，不再受约束, 接口丰富，支持长短信，签名可选。2020年4月8日，中国三大电信运营商联合发布《5G消息白皮书》，51短信平台也会全新升级到“51商用消息平台”，全面支持5G RCS消息。</p>
<p>著名云主机服务厂商DigitalOcean发布最新的主机计划，入门级Droplet配置升级为：1 core CPU、1G内存、25G高速SSD，价格5$/月。有使用DigitalOcean需求的朋友，可以打开这个<a href="https://m.do.co/c/bff6eed92687">链接地址</a>：https://m.do.co/c/bff6eed92687 开启你的DO主机之路。</p>
<p>Gopher Daily(Gopher每日新闻)归档仓库 &#8211; https://github.com/bigwhite/gopherdaily</p>
<p>我的联系方式：</p>
<ul>
<li>微博：https://weibo.com/bigwhite20xx</li>
<li>微信公众号：iamtonybai</li>
<li>博客：tonybai.com</li>
<li>github: https://github.com/bigwhite</li>
<li>“Gopher部落”知识星球：https://public.zsxq.com/groups/51284458844544</li>
</ul>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p>微信赞赏：<br />
<img src="https://tonybai.com/wp-content/uploads/wechat-zanshang-code-512x512.jpg" alt="img{512x368}" /></p>
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。</p>
<p style='text-align:left'>&copy; 2021, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2021/11/11/go-opensource-12-years/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>vim-go更新小记</title>
		<link>https://tonybai.com/2016/09/08/upgrade-vim-go/</link>
		<comments>https://tonybai.com/2016/09/08/upgrade-vim-go/#comments</comments>
		<pubDate>Thu, 08 Sep 2016 14:45:41 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[atom]]></category>
		<category><![CDATA[brew]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Emacs]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[gocode]]></category>
		<category><![CDATA[godef]]></category>
		<category><![CDATA[goimports]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[golint]]></category>
		<category><![CDATA[gometalinter]]></category>
		<category><![CDATA[guru]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[intellij]]></category>
		<category><![CDATA[liteide]]></category>
		<category><![CDATA[Lua]]></category>
		<category><![CDATA[MacVim]]></category>
		<category><![CDATA[neocomplete]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[sublimetext3]]></category>
		<category><![CDATA[ultisnips]]></category>
		<category><![CDATA[Vim]]></category>
		<category><![CDATA[vim-go]]></category>
		<category><![CDATA[vim-plug]]></category>
		<category><![CDATA[vimrc]]></category>
		<category><![CDATA[vscode]]></category>
		<category><![CDATA[vundle.vim]]></category>
		<category><![CDATA[编辑器]]></category>
		<category><![CDATA[补齐]]></category>

		<guid isPermaLink="false">http://tonybai.com/?p=2019</guid>
		<description><![CDATA[自从上一次配置好Mac上的Golang Vim开发环境，基本上就没怎么动过。近两年过去了，Go已经升级到了1.7版本，Vim-go截至目前也已经演化到了1.8版本了。社区的积极关注和使用，让Vim-go的作者Fatih Arslan备受鼓舞，于是近一年来，积极为vim-go添加新功能，发布新版本，并编写了vim-go的详细tutorial。这让我动了更新Vim-go版本的念头，于是就有了本篇内容。 已经记不得当初第一次配置vim-go时，vim-go的版本号是多少了。经过近两年的发展，vim-go已然正式成为Vim下Go开发环境的标准Plugin了。Go从当年的1.4升级到1.7，相关工具也跟着一起升级，比如oracle变成了guru，名字都换了。支持go的编辑器也逐渐增多并日益成熟，从最初vim、liteIDE，到后来的eclipse、IntelliJ Idea、atom、sublime text以及vscode对golang都提供了支持。这样一来，无论你之前是哪种IDE的拥趸，你都能找到得心应手的环境走入Golang世界。 我个人一直用vim，sublime text3曾经玩过，没玩熟，卸了。目前机器上还装了一份vscode，感觉在IDE领域中，微软的影响力和成熟度不容小觑，vscode + golang extension从入门门槛来看，还是非常低的。即便vim-go进化到1.8版本，仍然不如vscode安装体验来得方便。当然这不全是vim-go的问题，而是vim的设计哲学所致。 无论是vim-go还是vscode golang plugin，都要依赖golang的周边工具，主要包括gocode、goimports、guru、godef、golint、gometalinter等。在这方面，vim-go提供了安装依赖工具的方法“:GoInstallBinaries”，或在外部通过：vim -c “GoInstallBinaries” -c “qa”安装（在安装vim-go之后）；而vscode则会自动探测其所依赖的工具是否安装，如果没有安装，会在vscode的下方给出提示，点击提示，会安装相应的工具。 BTW，自从近期golang官网：golang.org不用再翻墙后，go get下载golang.org域名下面的各种工具也简单了许多，大陆的Gopher们再也无需担心go package下载的问题了。 升级vim-go之前，建议先备份好.vimrc文件： cp .vimrc .vimrc.bak.20160908 vim-go插件安装由很多方法，在vim-go tutorial中，vim-go作者选择了vim-plug，而没有用之前的vim插件管理工具vundle.vim，方法都是大同小异： 下载vim-plug： $curl -fLo ~/.vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 67682 100 67682 [...]]]></description>
			<content:encoded><![CDATA[<p>自从上一次配置好Mac上的<a href="http://tonybai.com/2014/11/07/golang-development-environment-for-vim/">Golang Vim开发环境</a>，基本上就没怎么动过。近两年过去了，<a href="http://tonybai.com/2016/06/21/some-changes-in-go-1-7/">Go已经升级到了1.7版本</a>，<a href="https://github.com/fatih/vim-go">Vim-go</a>截至目前也已经演化到了<a href="https://github.com/fatih/vim-go/releases/tag/v1.8">1.8版本</a>了。社区的积极关注和使用，让Vim-go的作者<a href="https://github.com/fatih">Fatih Arslan</a>备受鼓舞，于是近一年来，积极为vim-go添加新功能，发布新版本，并编写了vim-go的详细<a href="https://github.com/fatih/vim-go-tutorial">tutorial</a>。这让我动了更新Vim-go版本的念头，于是就有了本篇内容。</p>
<p>已经记不得当初第一次配置vim-go时，vim-go的版本号是多少了。经过近两年的发展，vim-go已然正式成为Vim下Go开发环境的标准Plugin了。Go从当年的<a href="http://tonybai.com/2014/11/04/some-changes-in-go-1-4/">1.4</a>升级到1.7，相关工具也跟着一起升级，比如oracle变成了<a href="https://github.com/golang/tools/tree/master/cmd/guru">guru</a>，名字都换了。支持go的编辑器也逐渐增多并日益成熟，从最初<a href="http://tonybai.com/tag/vim">vim</a>、<a href="https://github.com/visualfc/liteide">liteIDE</a>，到后来的<a href="http://www.eclipse.org/">eclipse</a>、<a href="https://github.com/go-lang-plugin-org/go-lang-idea-plugin">IntelliJ Idea</a>、<a href="https://atom.io/packages/go-plus">atom</a>、<a href="http://www.sublimetext.com/">sublime text</a>以及<a href="https://github.com/microsoft/vscode-go">vscode</a>对golang都提供了支持。这样一来，无论你之前是哪种IDE的拥趸，你都能找到得心应手的环境走入Golang世界。</p>
<p>我个人一直用vim，sublime text3曾经玩过，没玩熟，卸了。目前机器上还装了一份vscode，感觉在IDE领域中，微软的影响力和成熟度不容小觑，vscode + golang extension从入门门槛来看，还是非常低的。即便vim-go进化到1.8版本，仍然不如vscode安装体验来得方便。当然这不全是vim-go的问题，而是vim的设计哲学所致。</p>
<p>无论是vim-go还是vscode golang plugin，都要依赖golang的周边工具，主要包括<a href="https://github.com/nsf/gocode">gocode</a>、<a href="https://github.com/golang/tools/tree/master/cmd/goimports">goimports</a>、<a href="https://github.com/golang/tools/tree/master/cmd/guru">guru</a>、<a href="https://github.com/rogpeppe/godef">godef</a>、<a href="https://github.com/golang/lint/golint">golint</a>、<a href="https://github.com/alecthomas/gometalinter">gometalinter</a>等。在这方面，vim-go提供了安装依赖工具的方法“:GoInstallBinaries”，或在外部通过：vim -c “GoInstallBinaries” -c “qa”安装（在安装vim-go之后）；而vscode则会自动探测其所依赖的工具是否安装，如果没有安装，会在vscode的下方给出提示，点击提示，会安装相应的工具。</p>
<p>BTW，自从近期golang官网：golang.org不用再翻墙后，go get下载golang.org域名下面的各种工具也简单了许多，大陆的Gopher们再也无需担心go package下载的问题了。</p>
<p>升级vim-go之前，建议先备份好.vimrc文件：</p>
<pre><code>cp .vimrc .vimrc.bak.20160908
</code></pre>
<p>vim-go插件安装由很多方法，在vim-go tutorial中，vim-go作者选择了<a href="https://github.com/junegunn/vim-plug">vim-plug</a>，而没有用之前的vim插件管理工具<a href="https://github.com/VundleVim/Vundle.vim">vundle.vim</a>，方法都是大同小异：</p>
<p>下载vim-plug：</p>
<pre><code>$curl -fLo ~/.vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 67682  100 67682    0     0   7020      0  0:00:09  0:00:09 --:--:-- 12576
</code></pre>
<p>安装vim-go：</p>
<p>在.vimrc中填写如下内容：</p>
<pre><code>call plug#begin()
Plug 'fatih/vim-go'
</code></pre>
<p>然后执行”:PlugInstall”即可。</p>
<p>在安装依赖工具期间，发现mac原生自带的vim(macvim，又叫mvim，安装在/usr/local/bin/mvim)版本还是7.3.xx版本，无法满足一些工具的要求，于是通过brew安装vim(安装在/usr/local/Cellar/vim/7.4.2334/bin/vim)，然后通过/usr/bin/vim的一个符号链接连过去即可。</p>
<pre><code>$ll /usr/bin|grep vim
lrwxr-xr-x     1 root   wheel        38  9  8 16:21 vim@ -&gt; /usr/local/Cellar/vim/7.4.2334/bin/vim
... ...
</code></pre>
<p>注意，考虑要安装<a href="https://github.com/Shougo/neocomplete.vim">neocomplete</a>以支持实时completion（补齐），vim需要有lua支持，因此执行brew install时要带上&#8211;with-lua参数：</p>
<pre><code>brew install vim --with-lua
</code></pre>
<p>vim-go升级版安装后，可按照vim-go-tutorial中的步骤，体验一下vim-go的强大，同时对.vimrc进行相关配置，并安装缺失的vim插件，比如neocomplete、<a href="https://github.com/SirVer/ultisnips">UltiSnips</a>等。我针对vim-go 1.8配置好的.vimrc在<a href="https://github.com/bigwhite/experiments/blob/master/vim_scripts/vimrc-for-vimgo-1.8">这里</a>可以下载到。</p>
<p>具体细节这里就不提了，如果还有哪些细节不清楚或实验没成功，可以回过头参考我那篇《<a href="http://tonybai.com/2014/11/07/golang-development-environment-for-vim/">Golang开发环境搭建-Vim篇</a>》。</p>
<p style='text-align:left'>&copy; 2016, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2016/09/08/upgrade-vim-go/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Golang开发环境搭建-Vim篇</title>
		<link>https://tonybai.com/2014/11/07/golang-development-environment-for-vim/</link>
		<comments>https://tonybai.com/2014/11/07/golang-development-environment-for-vim/#comments</comments>
		<pubDate>Fri, 07 Nov 2014 13:36:02 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[Editor]]></category>
		<category><![CDATA[errcheck]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[go.tools]]></category>
		<category><![CDATA[gocode]]></category>
		<category><![CDATA[godef]]></category>
		<category><![CDATA[goimports]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[golint]]></category>
		<category><![CDATA[gorename]]></category>
		<category><![CDATA[gosublime]]></category>
		<category><![CDATA[hg]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[MacVim]]></category>
		<category><![CDATA[Mercurial]]></category>
		<category><![CDATA[MolokaiTheme]]></category>
		<category><![CDATA[neocomplete]]></category>
		<category><![CDATA[neosnippet]]></category>
		<category><![CDATA[pathogen]]></category>
		<category><![CDATA[SublimeText2]]></category>
		<category><![CDATA[sublimetext3]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[ultisnips]]></category>
		<category><![CDATA[Vim]]></category>
		<category><![CDATA[vim-go]]></category>
		<category><![CDATA[vimrc]]></category>
		<category><![CDATA[Vundle]]></category>
		<category><![CDATA[YCM]]></category>
		<category><![CDATA[代码补齐]]></category>
		<category><![CDATA[编辑器]]></category>
		<category><![CDATA[语法高亮]]></category>

		<guid isPermaLink="false">http://tonybai.com/?p=1613</guid>
		<description><![CDATA[虽说sublimetext3+gosublime+gocode是目前较为 流行的Golang开发环境组合，但作为一名VIMer，没有一套得心应手的Vim for Golang dev心里总是过不去的。Golang虽然年轻，但即便是从Go 1版本发布(2012年3月28日)算起，掐指算来也有小三年了。全世界的开发者已经为Golang贡献了较为成熟的Vim插件了。有了这些插件，搭建出 一套高效的Golang开发环境还是不难的，网上也有大量的资料可以参考，其中就有vim-go作者自己发表的一篇文章《Go development environment for Vim》。不过看别人 写的与自己搭建体验的还是有大不同的，于是想来想去还是把整个过程记录下来。 一、一个干净的环境 找个干净的基础环境，方便确认每个搭建步骤后的效果： Ubuntu 14.04 x86_64 vim version 7.4.52 go version go1.4beta1 linux/amd64 再准备一个编辑Go源码的测试源文件： //hellogolang.go package main import &#34;fmt&#34; func main() { &#160;&#160;&#160;&#160;&#160;&#160;&#160; fmt.Println(&#34;Hello Golang!&#34;) } 用于验证每个搭建步骤后的变化。 二、严格按照vim-go的官方说明逐一搭建 Vim-go是当前使用最为广泛的用于搭建Golang开发环境的vim插件，这里我同样使用vim-go作为核心和基础进行环境搭建的。vim-go利 用开源Vim插件管理器安装，gmarik/Vundle.vim是目前被推荐次数更多的Vim插件管理器，超过了pathogen。这里我们 就用vundle来作为Vim的插件管理工具。 1、安装Vundle.vim Vundle.vim的安装步骤如下： mkdir ~/.vim/bundle git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim&#160;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 创建~/.vimrc文件(如果你没有这个文件的话)，在文件顶部添加有关Vundle.vim的配置： set nocompatible&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#34; [...]]]></description>
			<content:encoded><![CDATA[<p>虽说<font face="Courier New"><a href="http://www.sublimetext.com/3">sublimetext3</a>+<a href="https://github.com/DisposaBoy/GoSublime">gosublime</a>+<a href="https://github.com/nsf/gocode">gocode</a></font>是目前较为 流行的<a href="http://tonybai.com/tag/go">Golang</a>开发环境组合，但作为一名VIMer，没有一套得心应手的<a href="http://www.vim.org/">Vim</a> for Golang dev心里总是过不去的。Golang虽然年轻，但即便是从<a href="http://tonybai.com/2014/10/25/golang-history/">Go 1版本发布</a>(2012年3月28日)算起，掐指算来也有小三年了。全世界的开发者已经为Golang贡献了较为成熟的Vim插件了。有了这些插件，搭建出 一套高效的Golang开发环境还是不难的，网上也有大量的资料可以参考，其中就有<a href="https://github.com/fatih/vim-go">vim-go</a>作者自己发表的一篇文章《<a href="http://blog.gopheracademy.com/vimgo-development-environment/">Go development environment for Vim</a>》。不过看别人 写的与自己搭建体验的还是有大不同的，于是想来想去还是把整个过程记录下来。</p>
<p><b>一、一个干净的环境</b></p>
<p>找个干净的基础环境，方便确认每个搭建步骤后的效果：</p>
<p><font face="Courier New"><a href="http://tonybai.com/2014/09/26/install-docker-on-ubuntu-server-1404/">Ubuntu 14.04</a> x86_64<br />
	vim version 7.4.52<br />
	go version go1.4beta1 linux/amd64</font></p>
<p>再准备一个编辑Go源码的测试源文件：</p>
<p><font face="Courier New">//hellogolang.go</font></p>
<p><font face="Courier New">package main</font></p>
<p><font face="Courier New">import &quot;fmt&quot;</font></p>
<p><font face="Courier New">func main() {<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fmt.Println(&quot;Hello Golang!&quot;)<br />
	}</font></p>
<p>用于验证每个搭建步骤后的变化。</p>
<p><b>二、严格按照vim-go的官方说明逐一搭建</b></p>
<p>Vim-go是当前使用最为广泛的用于搭建Golang开发环境的vim插件，这里我同样使用vim-go作为核心和基础进行环境搭建的。vim-go利 用开源Vim插件管理器安装，<a href="https://github.com/gmarik/Vundle.vim">gmarik/Vundle.vim</a>是目前被推荐次数更多的Vim插件管理器，超过了<a href="http://www.vim.org/scripts/script.php?script_id=2332">pathogen</a>。这里我们 就用vundle来作为Vim的插件管理工具。</p>
<p><b>1、安装Vundle.vim</b></p>
<p>Vundle.vim的安装步骤如下：</p>
<p><font face="Courier New">mkdir ~/.vim/bundle<br />
	git clone <a class="moz-txt-link-freetext" href="https://github.com/gmarik/Vundle.vim.git">https://github.com/gmarik/Vundle.vim.git</a> ~/.vim/bundle/Vundle.vim&nbsp;&nbsp;&nbsp;</font> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p>创建<font face="Courier New">~/.vimrc</font>文件(如果你没有这个文件的话)，在文件顶部添加有关Vundle.vim的配置：</p>
<p><font face="Courier New">set nocompatible&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot; be iMproved, required<br />
	filetype off&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot; required</font></p>
<p><font face="Courier New">&quot; set the runtime path to include Vundle and initialize<br />
	set rtp+=~/.vim/bundle/Vundle.vim<br />
	call vundle#begin()</font></p>
<p><font face="Courier New">&quot; let Vundle manage Vundle, required<br />
	Plugin &#39;gmarik/Vundle.vim&#39;</font></p>
<p><font face="Courier New">&quot; All of your Plugins must be added before the following line<br />
	call vundle#end()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot; required<br />
	filetype plugin indent on&nbsp;&nbsp;&nbsp; &quot; required</font></p>
<p>此时Vim仅安装了Vundle.vim这一个插件。编辑hellogolang.go时与编辑普通文本文件无异，一切都还是Vim的默认属性。</p>
<p><b>2、安装Vim-go</b></p>
<p>编辑<font face="Courier New">~/.vimrc</font>，在<font face="Courier New">vundle#begin</font>和<font face="Courier New">vundle#end</font>间增加一行：</p>
<p><font face="Courier New">Plugin &#39;fatih/vim-go&#39;</font></p>
<p>在Vim内执行<font face="Courier New"> <img src='https://tonybai.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> luginInstall</font>，</p>
<p>Vundle.vim会在左侧打开一个Vundle Installer Preview子窗口，窗口下方会提示：<font face="Courier New">&ldquo;Processing &#39;fatih/vim-go&#39;&rdquo;</font>，待安装完毕后，提示信息变 成&ldquo;<font face="Courier New">Done!&rdquo;。</font></p>
<p><font face="Courier New">这时，我们可以看到.vim/bundle下多了一个vim-go文件夹：</font></p>
<p><font face="Courier New">$ ls .vim/bundle/<br />
	vim-go/&nbsp; Vundle.vim/</font></p>
<p>此时，再次编辑hellogolang.go，<u><b>语法高亮</b></u>有了， <u><b>保存时自动format</b></u>（利用$GOBIN/gofmt）也有了，但其他高级功能，比如自动import缺失的 package、自动补齐仍然没有，我们还要继续安装一些东东。</p>
<p><b>3、安装go.tools Binaries</b></p>
<p>vim-go安装说明中提到所有必要的binary需要先安装好，比如gocode、godef、goimports等。</p>
<p>通过<font face="Courier New">:GoInstallBinaries</font>，这些vim-go依赖的二进制工具将会自动被下载，并被安装到<font face="Courier New">$GOBIN</font>下或<font face="Courier New">$GOPATH/bin</font>下。（这个工具需要依赖git或hg，需要提前安装到你的OS中。）</p>
<p><font face="Courier New">:GoInstallBinaries</font>的执行是交互式的，你需要回车确认：</p>
<p><font face="Courier New">vim-go: gocode not found. Installing github.com/nsf/gocode to folder /home/tonybai/go/bin<br />
	vim-go: goimports not found. Installing code.google.com/p/go.tools/cmd/goimports to folder /home/tonybai/go/bin/<br />
	vim-go: godef not found. Installing code.google.com/p/rog-go/exp/cmd/godef to folder /home/tonybai/go/bin/<br />
	vim-go: oracle not found. Installing code.google.com/p/go.tools/cmd/oracle to folder /home/tonybai/go/bin/<br />
	vim-go: gorename not found. Installing code.google.com/p/go.tools/cmd/gorename to folder /home/tonybai/go/bin/<br />
	vim-go: golint not found. Installing github.com/golang/lint/golint to folder /home/tonybai/go/bin/</font><br />
	<font face="Courier New">vim-go: errcheck not found. Installing github.com/kisielk/errcheck to folder /home/tonybai/go/bin/</font></p>
<p>不过这些代码多在code.google.com上托管，因此由于众所周知的原因，vim-go的自动安装很可能以失败告终，这样就需要你根据上 面日志中提到的各个工具的源码地址逐一去下载并本地安装。无法搭梯子的，可以通过http://gopm.io 下载相关包。</p>
<p>安装后，$GOBIN下的新增Binaries如下：<br />
	<font face="Courier New">-rwxr-xr-x&nbsp; 1 tonybai tonybai&nbsp; 5735552 11??&nbsp; 7 11:03 errcheck*<br />
	-rwxr-xr-x&nbsp; 1 tonybai tonybai&nbsp; 9951008 11??&nbsp; 7 10:33 gocode*<br />
	-rwxr-xr-x&nbsp; 1 tonybai tonybai&nbsp; 5742800 11??&nbsp; 7 11:07 godef*<br />
	-rwxr-xr-x&nbsp; 1 tonybai tonybai&nbsp; 4994120 11??&nbsp; 7 11:00 goimports*<br />
	-rwxr-xr-x&nbsp; 1 tonybai tonybai&nbsp; 5750152 11??&nbsp; 7 11:03 golint*<br />
	-rwxr-xr-x&nbsp; 1 tonybai tonybai&nbsp; 6381832 11??&nbsp; 7 11:01 gorename*<br />
	-rwxr-xr-x&nbsp; 1 tonybai tonybai&nbsp; 2954392 11??&nbsp; 7 10:38 gotags*<br />
	-rwxr-xr-x&nbsp; 1 tonybai tonybai&nbsp; 9222856 11??&nbsp; 7 11:01 oracle*</font></p>
<p>安装好这些Binaries后，我们来看看哪些特性被支持了。</p>
<p>再次编辑<font face="Courier New">hellogolang.go</font>：</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face="Courier New">- 新起一行输入fmt.，然后ctrl+x, ctrl+o，Vim 会弹出补齐提示下拉框，不过并非实时跟随的那种补齐，这个补齐是由gocode提供的。<br />
	&nbsp;&nbsp;&nbsp; &#8211; 输入一行代码：time.Sleep(time.Second)，执行:GoImports，Vim会自动导入time包。<br />
	&nbsp;&nbsp;&nbsp; &#8211; 将光标移到Sleep函数上，执行:GoDef或命令模式下敲入gd，Vim会打开$GOROOT/src/time/sleep.go中 的Sleep函数的定义。执行:b 1返回到hellogolang.go。<br />
	&nbsp;&nbsp;&nbsp; &#8211; 执行:GoLint，运行golint在当前Go源文件上。<br />
	&nbsp;&nbsp;&nbsp; &#8211; 执行:GoDoc，打开当前光标对应符号的Go文档。<br />
	&nbsp;&nbsp;&nbsp; &#8211; 执行:GoVet，在当前目录下运行go vet在当前Go源文件上。<br />
	&nbsp;&nbsp;&nbsp; &#8211; 执行:GoRun，编译运行当前main package。<br />
	&nbsp;&nbsp;&nbsp; &#8211; 执行:GoBuild，编译当前包，这取决于你的源文件，GoBuild不产生结果文件。<br />
	&nbsp;&nbsp;&nbsp; &#8211; 执行:GoInstall，安装当前包。<br />
	&nbsp;&nbsp;&nbsp; &#8211; 执行:GoTest，测试你当前路径下地_test.go文件。<br />
	&nbsp;&nbsp;&nbsp; &#8211; 执行:GoCoverage，创建一个测试覆盖结果文件，并打开浏览器展示当前包的情况。<br />
	&nbsp;&nbsp;&nbsp; &#8211; 执行:GoErrCheck，检查当前包种可能的未捕获的errors。<br />
	&nbsp;&nbsp;&nbsp; &#8211; 执行:GoFiles，显示当前包对应的源文件列表。<br />
	&nbsp;&nbsp;&nbsp; &#8211; 执行:GoDeps，显示当前包的依赖包列表。<br />
	&nbsp;&nbsp;&nbsp; &#8211; 执行:GoImplements，显示当前类型实现的interface列表。<br />
	&nbsp;&nbsp;&nbsp; &#8211; 执行:GoRename [to]，将当前光标下的符号替换为[to]。</font></p>
<p><b>三、其他插件</b></p>
<p>到目前为止，我们还有若干特性没能实现，重点是：</p>
<p><font face="Courier New">&nbsp;&nbsp;&nbsp; &#8211; 实时跟随的代码补齐<br />
	&nbsp;&nbsp;&nbsp; &#8211; Code Snippet support</font></p>
<p><b>1、安装<a href="https://github.com/Valloric/YouCompleteMe">YCM</a>(Your Complete Me)</b></p>
<p>在~/.vimrc中添加一行：</p>
<p><font face="Courier New">Plugin &#39;Valloric/YouCompleteMe&#39;</font></p>
<p>保存退出后，再打开~/.vimrc并执行<font face="Courier New"> <img src='https://tonybai.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> luginInstall</font>。</p>
<p>安装完后，下面的提示栏提示：</p>
<p><font face="Courier New">ycm_client_support.[so|pyd|dll] and ycm_core.[so|pyd|dll] not detected; you need to compile YCM before using it. Read the docs!</font></p>
<p>似乎YCM是用了C++编写的模块对性能进行优化了，于是需要手工编译YCM的support库。步骤如下：</p>
<p><font face="Courier New">sudo apt-get install build-essential cmake python-dev<br />
	cd ~/.vim/bundle/YouCompleteMe<br />
	./install.sh</font></p>
<p>构建（编译C++很慢，需要耐心的等一会）ok后，再打开hellogolang.go，逐字的实时补全功能就具备了！Cool！</p>
<p><b>2、安装</b> <a href="https://github.com/SirVer/ultisnips"><b>UltiSnips</b></a></p>
<p>Vim-go默认是用ultisnips引擎插件，但这个插件需要单独安装。</p>
<p>同样，我们利用vundle来安装它，在~/.vimrc中添加一行：</p>
<p><font face="Courier New">Plugin &#39;SirVer/ultisnips&#39;</font></p>
<p>snippet和snippet引擎是分开的。ultisnips是引擎，vim-go的go snippet定义在这里</p>
<p><font face="Courier New"><a class="moz-txt-link-freetext" href="https://github.com/fatih/vim-go/blob/master/gosnippets/snippets/go.snip">https://github.com/fatih/vim-go/blob/master/gosnippets/snippets/go.snip</a></font></p>
<p>编辑hellogolang.go，按照go.snip中的说明，我们输入func后敲击tab键，我们发现期待的：</p>
<p><font face="Courier New">func name(params) type {<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
	}</font></p>
<p>并没有出现。反倒是YCM的下拉提示显示在那里让你选择。似乎是ultisnips和YCM的键组合冲突了。ultisnips官方说明也的确如 此。ultisnips默认是用Tab展开snippet的，而YCM中的Tab用来选择补齐项，我们可以通过设置来避免这些。</p>
<p>我们在.vimrc中添加如下setting：</p>
<p><font face="Courier New">&quot; YCM settings<br />
	let g:ycm_key_list_select_completion = [&#39;<enter>&#39;, &#39;<down>&#39;]<br />
	let g:ycm_key_list_previous_completion = [&#39;<up>&#39;]<br />
	let g:ycm_key_invoke_completion = &#39;&lt;C-Space&gt;&#39;</up></down></enter></font></p>
<p><font face="Courier New">&quot; UltiSnips setting<br />
	let g:UltiSnipsExpandTrigger=&quot;&lt;tab&gt;&quot;<br />
	let g:UltiSnipsJumpForwardTrigger=&quot;&lt;c-b&gt;&quot;<br />
	let g:UltiSnipsJumpBackwardTrigger=&quot;&lt;c-z&gt;&quot;</font></p>
<p>这样让YCM通过回车和向下的箭头来做list item正向选择，通过向上箭头做反向选择。通过ctrl+space来原地触发补齐提示。</p>
<p>而ultisnips则是用tab做snippet展开，ctrl+b正向切换占位符，ctrl+z反向切换占位符。</p>
<p><b>3、安装molokai theme</b></p>
<p>Molokai theme是TextMate的theme的vim port，看着截图挺不错的，于是也安装了一下。</p>
<p><font face="Courier New">&nbsp;&nbsp;&nbsp; mkdir ~/.vim/colors<br />
	&nbsp;&nbsp;&nbsp; 下载或copy <a class="moz-txt-link-freetext" href="https://github.com/fatih/molokai/blob/master/colors/molokai.vim%E5%88%B0%7E/.vim">https://github.com /fatih/molokai/blob/master/colors/molokai.vim到~/.vim</a> /colors目录下<br />
	&nbsp;&nbsp;&nbsp; 在.vimrc添加一行：colorscheme molokai</font></p>
<p><b>四、.vimrc</b></p>
<p>前面讲到了vim-go有许多命令，在:xx模式下执行多显不便，于是你可以定义一些Mappings，比如：</p>
<p><font face="Courier New">&quot; set mapleader<br />
	let mapleader = &quot;,&quot;</font></p>
<p><font face="Courier New">&quot; vim-go custom mappings<br />
	au FileType go nmap &lt;Leader&gt;s &lt;Plug&gt;(go-implements)<br />
	au FileType go nmap &lt;Leader&gt;i &lt;Plug&gt;(go-info)<br />
	au FileType go nmap &lt;Leader&gt;gd &lt;Plug&gt;(go-doc)<br />
	au FileType go nmap &lt;Leader&gt;gv &lt;Plug&gt;(go-doc-vertical)<br />
	au FileType go nmap &lt;leader&gt;r &lt;Plug&gt;(go-run)<br />
	au FileType go nmap &lt;leader&gt;b &lt;Plug&gt;(go-build)<br />
	au FileType go nmap &lt;leader&gt;t &lt;Plug&gt;(go-test)<br />
	au FileType go nmap &lt;leader&gt;c &lt;Plug&gt;(go-coverage)<br />
	au FileType go nmap &lt;Leader&gt;ds &lt;Plug&gt;(go-def-split)<br />
	au FileType go nmap &lt;Leader&gt;dv &lt;Plug&gt;(go-def-vertical)<br />
	au FileType go nmap &lt;Leader&gt;dt &lt;Plug&gt;(go-def-tab)<br />
	au FileType go nmap &lt;Leader&gt;e &lt;Plug&gt;(go-rename)</font></p>
<p>这样我们在命令模式下，输入<font face="Courier New">&lt;,&gt;+&lt;r&gt;</font>就是运行 当前main包，以此类推。</p>
<p>另外下面这个配置使得我们在save file时既可以格式化代码，又可以自动插入包导入语句（或删除不用的包导入语句）。</p>
<p><font face="Courier New">&quot; vim-go settings<br />
	let g:go_fmt_command = &quot;goimports&quot;</font></p>
<p>到这里，我们的Vim Golang开发环境就基本搭建好了。snippet+实时补齐让你Coding如飞！</p>
<p><b>五、附录：.vimrc文件</b></p>
<p>下面是截至目前为止全量.vimrc文件的内容：</p>
<p><font face="Courier New">set nocompatible&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot; be iMproved, required<br />
	filetype off&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot; required<br />
	colorscheme molokai</font></p>
<p><font face="Courier New">&quot; set the runtime path to include Vundle and initialize<br />
	set rtp+=~/.vim/bundle/Vundle.vim<br />
	call vundle#begin()</font></p>
<p><font face="Courier New">&quot; let Vundle manage Vundle, required<br />
	Plugin &#39;gmarik/Vundle.vim&#39;<br />
	Plugin &#39;fatih/vim-go&#39;<br />
	Plugin &#39;Valloric/YouCompleteMe&#39;</font></p>
<p><font face="Courier New">Plugin &#39;SirVer/ultisnips&#39;</font></p>
<p><font face="Courier New">&quot; All of your Plugins must be added before the following line<br />
	call vundle#end()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot; required<br />
	filetype plugin indent on&nbsp;&nbsp;&nbsp; &quot; required</font></p>
<p><font face="Courier New">&quot; set mapleader<br />
	let mapleader = &quot;,&quot;</font></p>
<p><font face="Courier New">&quot; vim-go custom mappings<br />
	au FileType go nmap &lt;Leader&gt;s &lt;Plug&gt;(go-implements)<br />
	au FileType go nmap &lt;Leader&gt;i &lt;Plug&gt;(go-info)<br />
	au FileType go nmap &lt;Leader&gt;gd &lt;Plug&gt;(go-doc)<br />
	au FileType go nmap &lt;Leader&gt;gv &lt;Plug&gt;(go-doc-vertical)<br />
	au FileType go nmap &lt;leader&gt;r &lt;Plug&gt;(go-run)<br />
	au FileType go nmap &lt;leader&gt;b &lt;Plug&gt;(go-build)<br />
	au FileType go nmap &lt;leader&gt;t &lt;Plug&gt;(go-test)<br />
	au FileType go nmap &lt;leader&gt;c &lt;Plug&gt;(go-coverage)<br />
	au FileType go nmap &lt;Leader&gt;ds &lt;Plug&gt;(go-def-split)<br />
	au FileType go nmap &lt;Leader&gt;dv &lt;Plug&gt;(go-def-vertical)<br />
	au FileType go nmap &lt;Leader&gt;dt &lt;Plug&gt;(go-def-tab)<br />
	au FileType go nmap &lt;Leader&gt;e &lt;Plug&gt;(go-rename)</font></p>
<p><font face="Courier New">&quot; vim-go settings<br />
	let g:go_fmt_command = &quot;goimports&quot;</font></p>
<p><font face="Courier New">&quot; YCM settings<br />
	let g:ycm_key_list_select_completion = [&#39;<enter>&#39;, &#39;<down>&#39;]<br />
	let g:ycm_key_list_previous_completion = [&#39;<s-enter>&#39;, &#39;<up>&#39;]<br />
	let g:ycm_key_invoke_completion = &#39;&lt;C-Space&gt;&#39;</up></s-enter></down></enter></font></p>
<p><font face="Courier New">&quot; UltiSnips settings<br />
	let g:UltiSnipsExpandTrigger=&quot;&lt;tab&gt;&quot;<br />
	let g:UltiSnipsJumpForwardTrigger=&quot;&lt;c-b&gt;&quot;<br />
	let g:UltiSnipsJumpBackwardTrigger=&quot;&lt;c-z&gt;&quot;</font></p>
<p><b>六、Mac OS X下Vim配置</b></p>
<p><b>1、MacVim替换</b></p>
<p>Mac OS X下的配置方法稍有不同，因为Mac下系统自带的Vim是7.3版本，YCM要求Vim 7.3.584+版本，因此我们需要安装MacVim以替代自带的Vim，目前MacVim最新版本是version 7.4.258，完全满足要求。在这里<font face="Courier New">https://github.com/b4winckler/macvim/releases</font>可以下载到最新的MacVim，下载后的MacVim可以通过如下步骤替换原Vim。</p>
<p>原Vim安装到/usr/bin/vim下。</p>
<p>MacVim解压后如下：</p>
<p><font face="Courier New">[tony@tonydeair ~/Downloads/MacVim-snapshot-73]$ls<br />
	MacVim.app/&nbsp;&nbsp;&nbsp; README.txt&nbsp;&nbsp;&nbsp; mvim*</font></p>
<p>我们执行以下步骤即可完成vim替换工作：</p>
<p><font face="Courier New">sudo mv /usr/bin/vim /usr/bin/vim.bak //备份一下原vim<br />
	cp mvim /usr/local/bin/<br />
	sudo ln -s /usr/local/bin/mvim /usr/bin/vim</font></p>
<p><b>2、插件安装和配置</b></p>
<p>按照上面Linux Vim的插件安装步骤和配置方法我们来配置MacVim，配置后，我们发现除了<font face="Courier New">molokai</font>的colorscheme没有生效外，其余插件工作均正常。而所有.go文件打开，均无molokai方案的颜色高亮，甚至连一般的颜色高亮都没有了。经过不断调试，发现了一个解决方法，在<font face="Courier New">~/.vimrc</font>中添加几行代码即可：</p>
<p><font face="Courier New"><b>syntax on</b><br />
	<b>au BufRead,BufNewFile *.go set filetype=go</b><br />
	colorscheme molokai</font></p>
<p>但这几行配置代码如果放在~/.vimrc的前面，则UltiSnips会无法工作，我将其移到~/.vimrc文件的末尾，这样就不存在冲突了（看来.vimrc的插件配置的先后顺序会对插件功能的正常使用有影响）。漂亮的molokai colorscheme也会展现出来！</p>
<p style='text-align:left'>&copy; 2014, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2014/11/07/golang-development-environment-for-vim/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hello，Sublime Text 2</title>
		<link>https://tonybai.com/2013/04/01/hello-sublime-text-2/</link>
		<comments>https://tonybai.com/2013/04/01/hello-sublime-text-2/#comments</comments>
		<pubDate>Mon, 01 Apr 2013 06:58:41 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Blogger]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Codecs26]]></category>
		<category><![CDATA[ConvertToUTF8]]></category>
		<category><![CDATA[Ctags]]></category>
		<category><![CDATA[GCC]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Opensource]]></category>
		<category><![CDATA[PackageControl]]></category>
		<category><![CDATA[Programmer]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[SublimeText2]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[Vim]]></category>
		<category><![CDATA[学习]]></category>
		<category><![CDATA[工作]]></category>
		<category><![CDATA[开源]]></category>
		<category><![CDATA[程序员]]></category>
		<category><![CDATA[编辑器]]></category>

		<guid isPermaLink="false">http://tonybai.com/?p=1238</guid>
		<description><![CDATA[用惯了Vim后，也会有一种尝试新Editor的冲动，这回Sublime Text 2满足了我的这个需求。据说Sublime Text是目前最火的代码编辑器之一，我周围为数不多的几个比较Geek的同事都已经开始使用Sublime Text 2或用了很长时间了，其官方网站首页的Feature Demo也的确非常地炫。 安装Sublime Text 2 我的实验环境Ubuntu 12.04.1 32-bit Desktop版，默认Ubuntu Unity桌面，iBus拼音输入法。 Sublime Text 2的安装极其简单，遵循着download（http://www.sublimetext.com/2） -&#62; unzip -&#62; add path -&#62; start and use的经典路线。我下载的Sublime Text 2是2.0.1版本，启动后一切正常。 安装后目录结构 安装后的Sublime Text 2的目录结构非常简洁： $ ls Icon/ &#160;PackageSetup.py &#160; Pristine Packages/ lib/ &#160; sublime_plugin.py &#160; sublime_text* lib下是自带的Python26环境；Pristine Packages下是各种编程语言的插件包。 在我的环境下Sublime Text 2的用户配置与包环境放在了~/.config/sublime-text-2/下面， $ ls Installed Packages/ &#160;Packages/ [...]]]></description>
			<content:encoded><![CDATA[<p>用惯了<a href="http://tonybai.com/2008/12/30/in-depth-study-vim/">Vim</a>后，也会有一种尝试新Editor的冲动，这回<a href="http://www.sublimetext.com/2">Sublime Text 2</a>满足了我的这个需求。据说Sublime Text是目前最火的代码编辑器之一，我周围为数不多的几个比较Geek的同事都已经开始使用Sublime Text 2或用了很长时间了，其官方网站首页的Feature Demo也的确非常地炫。</p>
<p><strong>安装Sublime Text 2</strong></p>
<p>我的实验环境<a href="http://tonybai.com/2012/12/04/upgrade-ubuntu-to-1204-lts/">Ubuntu 12.04.1</a> 32-bit Desktop版，默认Ubuntu Unity桌面，iBus拼音输入法。</p>
<p>Sublime Text 2的安装极其简单，遵循着download（http://www.sublimetext.com/2） -&gt; unzip -&gt; add path -&gt; start and use的经典路线。我下载的Sublime Text 2是2.0.1版本，启动后一切正常。</p>
<p><strong>安装后目录结构</strong></p>
<p>安装后的Sublime Text 2的目录结构非常简洁：</p>
<p><span style="font-family:courier new,courier,monospace;">$ ls<br />
	Icon/ &nbsp;PackageSetup.py &nbsp; Pristine Packages/<br />
	lib/ &nbsp; sublime_plugin.py &nbsp; sublime_text*</span></p>
<p>lib下是自带的Python26环境；Pristine Packages下是各种编程语言的插件包。</p>
<p>在我的环境下Sublime Text 2的用户配置与包环境放在了~/.config/sublime-text-2/下面，</p>
<p><span style="font-family:courier new,courier,monospace;">$ ls<br />
	Installed Packages/ &nbsp;Packages/ &nbsp;Pristine Packages/ &nbsp;Settings/</span></p>
<p>这里面最重要的目录就是Packages目录了，这里是Sublime Text 2用第三方包扩展自身Feature的包存储路径。</p>
<p><strong>安装package control</strong></p>
<p>package control包之于Sublime Text 2就好比apt工具之于Ubuntu，它是一个方便第三方包安装、卸载和管理的第三方包。在其官网(http://wbond.net/sublime_packages/package_control)上明示了其安装方法：</p>
<p>* 敲入 ctrl + ` 调出命令行窗口<br />
	* 在命令行窗口中输入下面的代码，回车执行。</p>
<p><span style="font-family:courier new,courier,monospace;">import urllib2,os; pf=&#39;Package Control.sublime-package&#39;; ipp=sublime.installed_packages_path(); os. &nbsp; &nbsp; &nbsp; &nbsp;makedirs(ipp) if not os.path.exists(ipp) else None; urllib2.install_opener(urllib2.build_opener(urllib2. &nbsp; ProxyHandler())); open(os.path.join(ipp,pf),&#39;wb&#39;).write(urllib2.urlopen(&#39;http://sublime.wbond.net/&#39;+pf.replace(&#39; &#39;,&#39;%20&#39;)).read()); print(&#39;Please restart Sublime Text to finish installation&#39;)</span></p>
<p>* 重启Sublime Text 2。</p>
<p>注意：如果需要代理访问外网的话，需要正确设置<a href="http://tonybai.com/2012/11/21/setup-http-proxy-with-squid/">http_proxy</a>环境变量。</p>
<p>敲入&quot;ctrl + shift + p&quot;可打开命令窗口，输入&quot;Package Control&quot;，你会看到窗口下拉提示中Package Control支持的功能，常用的我们会选择：&ldquo;Package Control: Install Package&rdquo;。</p>
<p><strong>安装中文支持</strong></p>
<p>中国程序员每每在尝试一种国外程序员新开发的编辑器时，都会遇到<a href="http://tonybai.com/2009/09/28/also-talk-about-vim-charset-configuration/">中文字符集编码</a>的问题，这次Sublime Text 2也不例外，它原生就不支持中文显示。还好中国程序员是无比聪明的，开发了<a href="https://github.com/seanliang/ConvertToUTF8">ConvertToUTF8</a>这样的第三方包，让我们可以看到中文并用中文编辑。</p>
<p>最简单的安装ConvertToUTF8的方法就是用Package Control安装，选择Package Control: Install Package后，搜素ConvertToUTF8，找到后，点击即可安装。安装后，你会在~/.config/sublime-text-2/Packages下面看到ConvertToUTF8包目录。</p>
<p>再次启动Sublime Text 2后，打开一个GBK编码的中文文档，居然提示ConvertToUTF8工作不正常。后发现ConvertToUTF8主页上有提示，Python 2.6下的ConvertToUTF8需要一个<a href="https://github.com/seanliang/Codecs26">Codecs26</a>的Package才能正常运行。下载Codecs26后，解压安装到Packages下面，重新启动Sublime Text 2，Sublime Text 2直接dump core。从Packages目录下将Codecs26删除后，Sublime Text 2恢复正常。</p>
<p>又细致读了ConvertToUTF8作者的README文件，发现master branch上的Codecs26是for 64位版本的，我需要下载x32 branch上的包。的确，下载并安装x32 branch上的Codecs26后，Sublime Text 2启动OK，转换中文OK了。</p>
<p>注意：不要与其他支持GBK转换的包（比如GBK Encoding Support）混用，否则ConvertToUTF8无法works。</p>
<p><strong>解决中文输入问题</strong></p>
<p>好不容易能看GBK编码的中文文件了，却发现无法输入中文，无论如何切换输入法和重启输入法，都无法输入中文。网上介绍可通过&quot;Input Helper Package（cd .config/sublime-text-2/Packages; git clone http://github.com/xgenvn/InputHelper.git）&quot;解决问题。问题的确可以解决，不过输入中文时太麻烦了：需要先敲入&quot;ctrl+shift+z&quot;调出中文输入框，再在这个框里输入中文。</p>
<p>网上都说这是iBus输入法与Sublime Text 2的兼容问题，要想解决就要换<a href="http://www.fcitx.org">fcitx</a>。以前用过fcitx感觉默认输入法比较弱，不过现在fcitx有google pinyin了，体验一定会提高不少。通过下面命令一键安装fcitx：</p>
<p><span style="font-family:courier new,courier,monospace;">sudo apt-get install fcitx fcitx-googlepinyin</span></p>
<p>安装后，在&ldquo;语言支持&rdquo;中用fcitx替换掉iBus。在&ldquo;启动应用程序&rdquo;中加入：</p>
<p><span style="font-family:courier new,courier,monospace;">名称: Fcitx<br />
	命令: /usr/bin/fcitx -d<br />
	注释t: Fcitx启动</span></p>
<p>注销再登录后，再打开Sublime Text 2，终于可以输入中文了。</p>
<p><strong>功能</strong></p>
<p>用了一遭儿，Sublime Text 2最吸引我的Feature包括：&ldquo;Goto Anything&rdquo;和&ldquo;Multi-Selection&rdquo;。在一个工程中，通过ctrl + p调出一个输入框，Sublime Text 2首先在文件名级别对你输入的文本进行匹配；待选择好文件后，继续输入@，可看到下拉列表中显示这个文件中所有函数名的名称列表；如果输入的是#，那么下拉列表中将显示该文件中的所有符号。选择某个函数名或符号后，光标将停留在某个符号上，这时我们可以用Multi-Selection这个功能了，如果你要将这个文件中同名符号全选出来，直接Alt+F3即可；如果要选择接下来的N个同名符号，那么敲入N次ctrl + D即可。</p>
<p>不过要想实现<a href="http://tonybai.com/2009/02/23/solve-some-problems-when-using-cscope/">ctags</a>那种在符号上跳转到符号定义或符号调用者的功能，Sublime Text 2还无法原生支持，可考虑安装Sublime Text 2的Ctags插件实现：直接在Packages目录下git clone https://github.com/SublimeText/CTags.git。之后：<br />
	- &ldquo;ctrl +t, ctrl+ r&quot;会重新生成tags文件(前提：系统内安装了ctags程序)<br />
	- &quot;ctrl +t, ctrl + t&quot;会跳到光标所在符号的定义处;<br />
	- &quot;ctrl + t, ctrl + b&quot;会跳回上次的位置;</p>
<p><strong>感受</strong></p>
<p>Sublime Text 2给我的最大感受就是&ldquo;快&rdquo;！你在搜索、切换符号、选择文件列表中文件或符号的同时，整个文件会同步的展现你的屏幕上。</p>
<p style='text-align:left'>&copy; 2013, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2013/04/01/hello-sublime-text-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Blogbus在线编辑器不支持代码缩进了</title>
		<link>https://tonybai.com/2007/12/10/the-editor-of-blogbus-do-not-support-indent/</link>
		<comments>https://tonybai.com/2007/12/10/the-editor-of-blogbus-do-not-support-indent/#comments</comments>
		<pubDate>Mon, 10 Dec 2007 05:10:21 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[杂货铺]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Blogbus]]></category>
		<category><![CDATA[博客]]></category>
		<category><![CDATA[生活]]></category>
		<category><![CDATA[编辑器]]></category>

		<guid isPermaLink="false">http://tonybai.com/2007/12/10/blogbus%e5%9c%a8%e7%ba%bf%e7%bc%96%e8%be%91%e5%99%a8%e4%b8%8d%e6%94%af%e6%8c%81%e4%bb%a3%e7%a0%81%e7%bc%a9%e8%bf%9b%e4%ba%86/</guid>
		<description><![CDATA[上周末提交了一篇&#34;符号连接那些事儿&#34;，但是从前台访问该文章后，发现文章里的代码缩进都被删除了，导致文章布局甚是难看。回到后台的文档编辑器，手工敲
入空格或TAB，提交后发现空格和TAB
仍然被过滤，今天和Blogbus客服沟通了一番，得知Blogbus在线编辑器对文章内容作了一次整体过滤和格式统一，这样就导致代码缩进被过滤了。
寒!]]></description>
			<content:encoded><![CDATA[<p>上周末提交了一篇&quot;<a href="http://tonybai.com/2007/12/08/those-things-about-symbol-linkage/">符号连接那些事儿</a>&quot;，但是从前台访问该文章后，发现文章里的代码缩进都被删除了，导致文章布局甚是难看。回到后台的文档编辑器，手工敲入空格或TAB，提交后发现空格和TAB 仍然被过滤，今天和<a href="http://bigwhite.blogbus.com">Blogbus</a>客服沟通了一番，得知Blogbus在线编辑器对文章内容作了一次整体过滤和格式统一，这样就导致代码缩进被过滤了。寒!</p>
<p>不过据客服说，如果文章第一次提交后未编辑修改，缩进还是可以保留的，所以以后再提交带有代码的文章，就要做好不修改的准备了，否则没有缩进的代码显示起来真的是很难看。</p>
<p>目前我尚未发现解决方法，即使用行号占位也无法支持缩进。</p>
<p>感谢客服已经将这个问题提交了，希望bus能尽早给出一个解决方案。比如在在线编辑器上提供一个插件，专门用来书写代码的，那样就好了。</p>
<p>下面的是测试第一次提交可以保留缩进：<br />
	int main() {<br />
	&nbsp;&nbsp; &nbsp;char *str = &quot;hello blogbus!\n&quot;;<br />
	&nbsp;&nbsp; &nbsp;printf(&quot;%s\n&quot;, str);<br />
	}</p>
<p style='text-align:left'>&copy; 2007, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2007/12/10/the-editor-of-blogbus-do-not-support-indent/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
