Go 的一大优势是「工具链自带」:格式化、测试、静态检查、文档、交叉编译都不需要额外安装。这一页把日常最常敲的 go 子命令、环境变量与构建标志整理成速查表。
下面所有命令都在本机 go1.27.0 上实测过,输出为真实结果。示例统一假设当前目录是一个 Go 模块(有 go.mod)。
常用 go 命令一览
| 命令 | 作用 | 何时用 |
|---|---|---|
go run . | 编译并运行 | 快速试跑 |
go build ./... | 编译,不运行 | 检查能否通过编译 |
go test ./... | 跑测试 | 每次改完代码 |
go vet ./... | 静态检查 | 提交前 |
gofmt -l -w . | 格式化并改写 | 提交前 |
go mod tidy | 整理依赖 | 增删 import 后 |
go doc <pkg>.<Sym> | 查文档 | 忘了签名时 |
go env | 查看环境变量 | 排查构建问题 |
日常循环基本是:gofmt -w . → go vet ./... → go test ./... → go build ./...。
构建与运行
go run 编译到临时目录并立即执行,适合开发期;go build 产出二进制,适合交付。go build 默认把结果放在当前目录,用 -o 指定输出路径。
| 命令 | 作用 |
|---|---|
go run ./cmd/app | 运行指定包 |
go build -o bin/taskapi ./cmd/app | 输出到指定路径 |
go build ./... | 编译所有包,不产出文件 |
go install ./cmd/... | 安装到 $GOBIN |
go build -trimpath -ldflags "-s -w -X main.version=1.0.0" -o bin/taskapi ./cmd/app
-trimpath 去掉构建路径、-s -w 去掉符号表与调试信息(体积更小)、-X main.version=... 在编译期注入版本号。用 var version = "dev" 接收它。
测试
| 命令 | 作用 |
|---|---|
go test ./... | 跑全部测试 |
go test -run TestName -v | 只跑匹配的测试,输出详细 |
go test -bench . -benchmem | 跑基准测试并报告内存分配 |
go test -cover | 报告语句覆盖率 |
go test -race | 开启竞态检测 |
go test -count=1 | 禁用结果缓存 |
go test -cover ./...
ok gtool 0.806s coverage: 100.0% of statements
go test -bench . -benchmem
BenchmarkSum-10 521093427 2.203 ns/op 0 B/op 0 allocs/op
-benchmem 会多报两列:每次操作分配多少字节、分配多少次——把分配次数压到 0 通常是性能优化的第一步。
代码质量:vet 与 fmt
| 命令 | 作用 |
|---|---|
gofmt -l . | 列出格式不规范的文件 |
gofmt -w . | 就地格式化 |
go fmt ./... | 等价于对包执行 gofmt -w |
go vet ./... | 检查可疑代码(如格式串与参数不匹配) |
gofmt -l .
(无输出表示全部合规。)gofmt 的输出是空或一串文件名,不会打印「成功」。go vet 只报「几乎肯定是 bug」的问题,能通过的代码未必对,但过不了的代码通常有问题。
模块:go mod
| 子命令 | 作用 |
|---|---|
go mod init example.com/taskapi | 初始化模块,生成 go.mod |
go mod tidy | 增删依赖,使 go.mod / go.sum 与代码一致 |
go mod download | 下载依赖到本地缓存 |
go mod vendor | 把依赖复制到 vendor/ |
go mod verify | 校验依赖内容与 go.sum 一致 |
go mod graph | 打印依赖图 |
go mod why <pkg> | 解释为何需要某个依赖 |
go.sum 记录每个依赖的校验和,防止内容被篡改;它应当与 go.mod 一起提交。
依赖:go get
| 命令 | 作用 |
|---|---|
go get example.com/pkg@latest | 拉取最新版 |
go get example.com/pkg@v1.2.3 | 指定版本 |
go get example.com/pkg@none | 移除依赖 |
go get -u ./... | 升级直接依赖到最新次版本 |
go get 会同时更新 go.mod 与 go.sum;改完记得跑 go mod tidy。
工作区:go work
| 子命令 | 作用 |
|---|---|
go work init ./a ./b | 创建 go.work,纳入多个模块 |
go work use ./c | 追加一个模块 |
go work sync | 同步工作区构建列表到各模块 |
go work vendor | 为工作区生成 vendor |
go.work 适合「同时改多个本地模块」的场景(比如主项目 + 本地工具库),不要提交到仓库,它是开发者的本地配置。
代码生成:go generate
go generate 扫描源码里的 //go:generate 指令并执行,常用于生成字符串方法、mock、序列化代码。
//go:generate stringer -type=Status
type Status int
go generate ./...
指令是普通命令,可以是任意可执行文件;go generate 本身不理解它们,只负责按注释里的顺序调用。
文档:go doc
| 命令 | 作用 |
|---|---|
go doc fmt.Errorf | 查某个符号的签名与说明 |
go doc net/http | 查整个包的概览 |
go doc -all net/http | 输出包的全部文档 |
go doc -src strings.Cut | 直接看源码实现 |
go doc strconv.ParseInt
func ParseInt(s string, base int, bitSize int) (i int64, err error)
忘了某个函数怎么用时,go doc 比搜索引擎更快,而且和你本机的版本完全一致。
环境:go env
go env GOOS GOARCH CGO_ENABLED GOPROXY GOVERSION
darwin
arm64
1
https://goproxy.cn,direct
go1.27.0
go env 不带参数会打印全部变量;带参数只打印指定项,适合脚本里取值。go env -w KEY=value 可持久化设置(写入 go env -w 配置文件)。
多版本工具链:GOTOOLCHAIN
当 go.mod 声明的版本高于本机 go 命令时,Go 会自动下载并使用匹配的工具链;GOTOOLCHAIN 控制这一行为。
| 取值 | 含义 |
|---|---|
auto(默认) | 优先用 go.mod 要求的版本,必要时下载 |
local | 只用本机已安装的 go 命令,不自动下载 |
go1.27.0 | 强制使用指定版本(如本机已缓存则直接切换) |
go1.27.2+auto | 指定下限,允许自动升级 |
GOTOOLCHAIN=go1.27.0 go version
go version go1.27.0 darwin/arm64
这套机制让「本机装旧版、项目要新版」不再冲突:一个命令前缀就能切换,无需手工管理多个 Go 安装。
常用环境变量
| 变量 | 作用 | 常见取值 |
|---|---|---|
GOOS / GOARCH | 目标操作系统 / 架构 | linux / windows;amd64 / arm64 |
CGO_ENABLED | 是否启用 cgo | 0 关闭(静态、易交叉编译) |
GOFLAGS | 追加默认参数 | -trimpath、-mod=mod |
GOPROXY | 模块代理 | https://goproxy.cn,direct |
GOTOOLCHAIN | 工具链选择 | auto / local / go1.27.0 |
GOMODCACHE | 模块缓存目录 | 默认 $GOPATH/pkg/mod |
GOCACHE | 构建缓存目录 | 默认用户缓存目录 |
查看全部:go env。临时改一个:GOOS=linux go build ./...。
构建标志速查
| 标志 | 作用 |
|---|---|
-o path | 指定输出文件 |
-race | 开启竞态检测(需要 cgo) |
-trimpath | 去掉源码绝对路径 |
-ldflags "-s -w" | 去符号表与调试信息,减小体积 |
-ldflags "-X main.version=1.0.0" | 注入版本号 |
-gcflags "-N -l" | 关闭优化与内联(调试用) |
-tags "linux,sqlite" | 指定构建标签 |
-buildmode=... | 构建模式(如 plugin) |
-mod=mod / -mod=readonly | 模块模式 |
交叉编译
Go 的交叉编译只需设置 GOOS / GOARCH,配合 CGO_ENABLED=0 得到静态二进制。
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -o bin/taskapi-linux ./cmd/app
GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -o bin/taskapi.exe ./cmd/app
go tool dist list | grep -E '^(linux|windows)/(amd64|arm64)$'
linux/amd64
linux/arm64
windows/amd64
windows/arm64
go tool dist list 列出全部受支持的 GOOS/GOARCH 组合。关闭 cgo 后的 Linux 二进制是静态链接的,可以直接放进 scratch 或 alpine 镜像,无需额外运行时。
小结
- 开发循环:
gofmt -w .→go vet ./...→go test ./...→go build ./...。 go run试跑,go build -o交付;-ldflags注入版本、-trimpath去掉路径。- 测试用
go test,-race查竞态、-cover看覆盖、-bench -benchmem看性能。 - 模块用
go mod init/tidy/vendor/verify,依赖用go get,多模块开发用go work。 - 忘了签名用
go doc,排查环境用go env。 - 多版本共存靠
GOTOOLCHAIN:auto自动切换、local只用本机、go1.27.0强制指定。 - 交叉编译只需
GOOS/GOARCH/CGO_ENABLED=0,go tool dist list查可用组合。
工具链的细节很多,但日常真正用到的就是上面这些。把「改完代码跑一遍 gofmt / vet / test」变成肌肉记忆,比记住每个标志更有价值。附录 D 会集中处理那些最常见的报错。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。