本文档介绍了 Go 编程语言、其仓库结构以及构成 Go 编程生态系统的主要组件。它涵盖了 Go 实现的关键架构元素,包括运行时系统、编译器、构建系统和标准库。
有关使用 Go 开发应用程序的具体详细信息,请参阅 语言规范和文档。
Go 是一种静态类型、编译型编程语言,由 Google 的 Robert Griesemer、Rob Pike 和 Ken Thompson 设计。它旨在实现简单、高效,并通过 goroutine 和 channel 内置对并发编程的支持。Go 将编译型语言的性能和类型安全性与动态语言的易用性和开发人员生产力相结合。
Go 的主要特点包括:
Go 的实现由多个相互关联的系统组成,如下图所示:
来源:src/runtime/proc.go22-32 doc/go_spec.html9-25 src/cmd/go/alldocs.go8-34
Go 仓库的组织结构如下:
| 目录 | 目的 |
|---|---|
src/ | 包含 Go 编程语言、运行时、编译器和标准库的源代码。 |
src/runtime/ | Go 运行时实现(垃圾收集器、调度器等) |
src/cmd/go/ | Go 命令行工具的实现 |
src/cmd/compile/ | Go 编译器实现 |
src/cmd/link/ | Go 链接器实现 |
doc/ | 文档,包括语言规范。 |
test/ | Go 实现的测试文件。 |
src/internal/ | 用于实现目的的内部包。 |
Go 的实现遵循了各种系统之间清晰的划分,它们之间有明确定义的接口。
来源:src/runtime/proc.go1-20 src/cmd/go/alldocs.go1-7
运行时系统是 Go 执行环境的核心。它实现了 goroutine 调度、内存管理、垃圾收集以及支持 Go 程序所需的其他低级功能等基本特性。
Go 调度器负责将 goroutine(轻量级线程)分发到可用的操作系统线程上。它实现了一个基于 G-P-M 模型的高级协作调度系统:
调度器使用工作窃取算法来保持所有 CPU 的忙碌。当一个 goroutine 阻塞时(例如,在 I/O 或 channel 操作上),运行时系统会从其 P 中分离 M,并调度另一个 goroutine 来运行。
来源:src/runtime/proc.go22-114 src/runtime/runtime2.go35-107 src/runtime/proc.go147-330
Go 使用自定义的内存分配器和垃圾收集器来自动管理内存。关键组件包括:
内存系统有几个层级:
来源:src/runtime/malloc.go5-76 src/runtime/mheap.go56-63 src/runtime/mbitmap.go5-17
Go 实现了一个并发的、三色标记清除垃圾收集器。它与应用程序并发运行,以最大限度地减少暂停时间。
垃圾收集过程有几个阶段:
垃圾收集器使用写屏障来跟踪在并发标记阶段修改的指针,确保不会遗漏任何对象。它还实现了比例调度,以确保 GC 工作分布在一段时间内。
来源:src/runtime/mgc.go5-118 src/runtime/mgcmark.go5-16 src/runtime/mgcsweep.go1-10 src/runtime/mgcpacer.go14-16
Go 编译器将 Go 源代码转换为机器码。它包含几个阶段:
Go 编译器旨在快速编译。它避免了复杂的、会减慢编译速度的优化,但仍然能生成相当高效的代码。
来源:src/cmd/go/internal/work/gc.go34-46
Go 构建系统由 go 命令实现,负责编译和链接 Go 程序。 go build 命令将包和依赖项编译成可执行二进制文件。
构建过程包括几个步骤
构建系统使用动作图来表示构建步骤之间的依赖关系。它可以并行构建多个包,并缓存构建结果以加快后续构建速度。
来源: src/cmd/go/internal/work/exec.go1-6 src/cmd/go/internal/work/build.go1-3 src/cmd/go/internal/work/exec.go72-238
Go 的构建系统包含包管理,现在主要通过 Go 模块来处理。模块是版本化的相关 Go 包的集合,由 go.mod 文件定义。
go 命令处理模块操作,例如
go get 解析和下载依赖项来源: src/cmd/go/alldocs.go669-710
Go 提供了一个全面的标准库,无需外部依赖即可提供基本功能。标准库组织成包,每个包专注于特定领域,如 I/O、网络、编码等。
标准库中的关键包包括
| 包 | 描述 |
|---|---|
fmt | 格式化 I/O,函数类似于 C 的 printf 和 scanf |
io | 基本 I/O 接口 |
net/http | HTTP 客户端和服务器实现 |
encoding/json | JSON 编码和解码 |
os | 操作系统功能 |
sync | 同步原语 |
time | 与时间相关的函数 |
标准库的设计强调简洁性、可组合性和一致性。
来源: src/cmd/go/internal/load/pkg.go57-146 src/runtime/time.go5-6
Go 内置了一个测试框架,位于 testing 包中。测试是写在文件名以 _test.go 结尾的文件中的函数。 go test 命令可以自动化运行测试。
测试框架支持
func TestXxx(*testing.T)func BenchmarkXxx(*testing.B)func ExampleXxx()func FuzzXxx(*testing.F)go test 命令处理测试发现、执行和报告。它还可以生成代码覆盖率报告并并行运行测试。
来源: src/cmd/go/internal/test/test.go52-177 src/cmd/go/internal/load/test.go1-3
Go 工具链包含多个支持 Go 开发的命令行工具
| 工具 | 描述 |
|---|---|
go build | 编译包和依赖项 |
go run | 编译并运行 Go 程序 |
go test | 测试包 |
go get | 将依赖项添加到当前模块并安装它们 |
go mod | 模块维护 |
go fmt | 格式化 Go 源代码 |
go vet | 报告包中可能存在的错误 |
go doc | 显示包或符号的文档 |
所有这些工具都集成到 go 命令中,它为 Go 工具链提供了统一的接口。
来源: src/cmd/go/alldocs.go14-34 src/cmd/go/internal/envcmd/env.go5-8 src/cmd/go/internal/help/helpdoc.go33-53
Go 的架构围绕协同工作的关键系统构建:运行时系统负责执行和内存管理,编译器将 Go 代码翻译成机器码,构建系统协调编译和链接,标准库提供基本功能。这种模块化设计使 Go 能够实现其简洁、高效和高生产力的目标。
有关特定组件的更详细信息,请参阅本手册的其他页面。