很多人第一次接触 Go 时,都会顺手问一句:Go 语言到底是用什么语言写的?这个问题表面上像在问实现细节,实际上会一路追到编译器从何而来、语言何时算真正成熟,以及“自举”为什么会被反复提起。
要把这件事讲清楚,可以分成两步看:先弄明白新语言最初为什么常常借助旧语言诞生,再看 Go 是怎样从 C 语言起步,最后把核心编译器逐步改写为 Go 自身。顺着这条线,你也更容易判断一门语言的工具链成熟度到底体现在哪里。
为什么新语言一开始离不开旧语言
理解这个问题,先要知道编译器在做什么。它负责把开发者写出的源代码翻译成机器可以执行的结果;如果没有编译器,再好的语言设计也无法真正落地。
难点在于,新语言刚诞生时,并不存在属于它自己的成熟工具链。也就是说,第一版编译器不可能凭空出现,通常只能借助已经足够稳定的语言来实现。这也是编程语言发展史里的常见路径:先用现成工具把第一版做出来,再慢慢过渡到“自己编译自己”。
Go 的最初实现就走了这条路,而当时最合适的“起点语言”是 C。原因并不神秘:
- C 语言长期用于系统编程,足够接近底层,便于处理运行时和编译器这种基础设施。
- C 语言诞生于 1972 年,生态成熟,几乎所有主流操作系统都能提供可用的 C 编译环境。
- 对于一门新语言来说,用 C 写出第一版编译器,是技术风险和工程成本都较可控的做法。
所以,回答“Go 是用什么语言写的”时,不能只看今天的代码仓库,还得把它诞生时的工程背景一起考虑进去。
Go 编译器是怎样从 C 走向自举的
Go 语言发布于 2009 年,由 Google 的三位设计者推动:Ken Thompson、Rob Pike 和 Robert Griesemer。对这样一门面向工程效率的语言来说,先把编译器做出来,比一开始就追求“纯粹自举”更重要。

因此,Go 的第一个编译器是用 C 语言编写的。这一步解决的是“先能用”的问题:先让 Go 代码可以被编译、运行,先建立起最基础的语言和工具链能力。
随后,Go 进入了更关键的阶段,也就是常说的自举。所谓自举,可以简单理解为:用目标语言自身来编写它自己的编译器。Go 的这条路不是一次性完成,而是渐进推进的。
- C 语言编译器阶段:最早先由 C 写出编译器,负责支持基础的 Go 语言能力。
- Go 语言重写阶段:在已有 C 编译器可用的前提下,开始把编译器的实现逐步转向 Go。
- 功能完善阶段:新的 Go 版编译器不断增强,逐步替代旧实现,补齐能力、性能和兼容性。
- 完全自举阶段:最终形成主要由 Go 语言自身实现的 Go 编译器。
这也是为什么这个问题的标准回答通常会分成“最初”和“现在”两部分:最初的 Go 编译器由 C 编写,现在的 Go 编译器主要由 Go 自身编写。
自举到底说明了什么
“能不能自举”并不只是一个技术圈里自娱自乐的话题,它通常意味着一门语言已经跨过了几个关键门槛。

语言本身足够成熟
如果一门语言已经能承担自己编译器的实现,说明它不仅能写业务代码,也能处理大型、复杂、对正确性要求极高的系统软件。这往往是成熟度的重要信号。
工具链进入正循环
当开发者用 Go 写 Go 编译器时,他们会更直接地使用这门语言本身的特性,也更容易暴露语言设计、标准库和工具链中的问题。编译器开发因此不只是“造工具”,也会反过来推动语言持续改进。
生态被高强度验证
编译器是最苛刻的软件之一。它对性能、稳定性、兼容性要求都很高。自举过程本身,就是对语言、运行时、构建系统和开发工具的一次长期压力测试。
不过,这并不意味着现在的 Go 工具链就完全只剩 Go 一种语言。更准确地说,Go 编译器是“以 Go 为主”的实现:
- Go 语言:承担核心编译逻辑的主要部分。
- 汇编语言:处理少量底层硬件相关工作。
- C 语言:在某些系统级接口或历史实现脉络中仍然扮演辅助角色。
因此,“Go 是不是纯粹用 Go 写的”这个问题,严格来说答案并不是绝对的是或否,而是要看你问的是核心编译器主体,还是整个工具链的全部组成部分。
这件事为什么值得开发者关心
很多人会把“编译器用什么写”视作偏底层的话题,但它其实会影响你对语言的实际判断。
首先,它能帮助你理解 Go 的工程风格。Go 从一开始就不是为了追求形式上的完美而设计的,而是明显偏向实用主义:先用 C 把基础设施落地,再逐步转向自举。这种路线和 Go 在语法、工具链、构建体验上的整体取向是一致的。
其次,它能帮助你评估语言的稳定性。通常来说,能够完成自举的语言,往往已经具备较成熟的编译能力、构建流程和社区维护基础。它不一定代表“最好”,但通常代表“已经经过足够多真实工程的检验”。
最后,这也是理解现代系统语言演进方式的一个窗口。Go 并不是特例,类似路径在其他语言中也存在。比如 Rust 也经历过从其他实现基础逐步走向自举的过程。新语言建立在旧技术之上,然后再反过来强化自身,这几乎已经成了现代编程语言发展的常见模式。
回到问题本身:Go 语言究竟是用什么写的
如果只要一句结论,可以这样回答:
Go 语言最早的编译器是用 C 语言写的;发展成熟后,现今的 Go 编译器主要使用 Go 语言自身实现,并辅以少量汇编和系统级支持代码。
所以,这个问题的关键不在于选一个单一答案,而在于分清“历史起点”和“当前状态”。前者解释了 Go 为什么能从零起步,后者说明它为什么已经被视为一门工具链成熟、工程属性很强的语言。









