覆盖 go build/test、go mod 依赖管理、gofmt/goimports、环境变量、go.mod 指令与交叉编译,每条附可直接照抄的示例和真实踩坑点

更新于 2026-09-24·适用版本:Go 1.27.x·共 35 条

构建、运行与测试日常写得最多的一组命令,全部支持 ./... 匹配当前模块下的所有包。

go build ./...

编译当前模块的所有包。不带 -o 时只检查能否编译,不会留下二进制文件。

示例
go build -o bin/app ./cmd/app

注意./... 不会包含 vendor 目录和子模块(各有自己 go.mod 的目录)。

go run .

编译到临时目录并立即运行,开发调试最常用。

示例
go run ./cmd/app --config dev.yaml

注意kill 掉 go run 进程不一定能杀掉它启动的子进程(程序本体),生产环境请用 go build 的产物。

go test ./...

运行全部测试。常用旗标:-v 详细输出、-run 按正则筛选、-race 竞态检测、-cover 覆盖率。

示例
go test -race -run TestParse ./pkg/parser/...
go test -coverprofile=cover.out ./... && go tool cover -html=cover.out

注意测试结果会被缓存,改了环境变量或外部文件不会使缓存失效——需要强制重跑时加 -count=1。

go vet ./...

官方静态检查:printf 参数错位、不可达代码、错误的 struct tag 等。

示例
go vet ./... && staticcheck ./...

注意vet 只覆盖一小类高置信问题,CI 里建议再挂 staticcheck(honest 地说:两者误报都很低)。

go install pkg@version

把命令行工具安装到 GOBIN(默认 ~/go/bin),管理全局工具的标准方式。

示例
go install golang.org/x/tools/cmd/goimports@latest
go install honnef.co/go/tools/cmd/staticcheck@2025.1

注意带 @版本号 时 go install 会忽略当前目录的 go.mod,在独立上下文中构建;想给项目加依赖请用 go get,不是 go install。

go clean -cache -modcache

清空构建缓存与模块下载缓存,排查「改了依赖却像没改」类怪问题的最后手段。

示例
go clean -cache
go clean -modcache   # 更狠:删掉全部已下载模块

注意-modcache 会删掉 GOMODCACHE 下所有模块,下次构建全量重新下载,CI 镜像里慎用。

模块与依赖管理go.mod / go.sum 的日常操作。排查依赖问题时先看 go mod graph 和 go mod why。

go mod init <path>

初始化模块,生成 go.mod。模块路径就是别人 import 你时用的路径。

示例
go mod init github.com/yourname/project

注意私有仓库也要用完整域名路径(如 git.company.com/team/proj),随便起个短名会让 go get 无法定位仓库。

go mod tidy

按代码里真实的 import 增删 go.mod 条目并补全 go.sum,提交前必跑。

示例
go mod tidy
go mod tidy -compat=1.26   # 兼容到指定旧版本

注意报 missing go.sum entry 时,先 go mod download <模块> 再 tidy;tidy 只扫描当前 GOOS/GOARCH 下的构建标签,跨平台代码注意 -compat。

go get pkg@version

添加、升级或降级依赖(只改 go.mod,不安装任何二进制)。

示例
go get github.com/gin-gonic/gin@latest
go get github.com/sirupsen/logrus@v1.9.3   # 降级同理

注意不带版本等价于 @upgrade,可能顺手升级一堆间接依赖;想最小改动就钉死版本号。

go list -m -u all

列出全部依赖及可升级版本([v1.2.3] 后缀表示有新版本)。

示例
go list -m -u all
go list -m -versions github.com/spf13/cobra   # 看某个模块的全部版本

注意all 包含间接依赖,输出会很长;只看直接依赖用 go list -m -u $(go list -m -f '{{if not .Indirect}}{{.Path}}{{end}}' all)。

go mod why <pkg>

回答「这个包到底是谁引进来的」:给出从 main 包到它的导入链。

示例
go mod why golang.org/x/sys
go mod graph | grep jwt   # 看完整的依赖图

注意why 显示的是「主模块视角」的链;要对比两个模块互相的版本要求,用 go mod graph。

go mod download

只下载依赖到本地缓存,不编译。CI 里用它预热缓存、加速后续构建。

示例
go mod download
go mod download github.com/gin-gonic/gin   # 只下载指定模块

注意go.sum 缺条目导致的构建失败,多半 download 一下对应模块就能修。

go mod verify

校验本地缓存里的模块与 go.sum 记录的哈希一致,防缓存被篡改。

示例
go mod verify

注意输出 all modules verified 才是通过;任何一行不匹配都说明缓存不可信,应 go clean -modcache。

格式化与代码工具gofmt 管格式,goimports 在此基础上管 import,两者区别详见本站博客专题。

gofmt -l -w .

格式化代码:-l 列出不符合规范的文件,-w 直接改写,-d 只看差异不改文件。

示例
gofmt -l .          # CI 检查:有输出即失败
gofmt -d main.go    # 看会改成什么样
gofmt -s -w .       # 同时做代码简化

注意gofmt 不会增删 import,也不会调整 import 分组——那是 goimports 的活,两者结果可以不一样。

goimports -l -w .

= gofmt + 自动补全/删除 import + 按标准库/第三方分组排序。

示例
go install golang.org/x/tools/cmd/goimports@latest
goimports -local github.com/myorg -w .   # 本地包单独一组

注意不加 -local 时,你自己公司的包会被归进「第三方」一组;首次在大仓库上运行会建索引,比较慢属正常。

go doc <pkg>.<symbol>

终端里查文档:包、函数、类型都可以,不用开浏览器。

示例
go doc net/http.Server
go doc json.Marshal
go doc github.com/gin-gonic/gin@latest   # 1.27 起支持 pkg@version

注意查未下载的第三方包会失败,先 go mod download 或加 @version 后缀。

go generate ./...

扫描源码里的 //go:generate 注释并执行对应命令(生成 mock、stringer 等)。

示例
//go:generate stringer -type=Status
go generate ./...

注意go generate 不是构建的一部分,go build 不会触发它——生成物要提交进仓库或写进 CI。

gofumpt -l -w .

第三方更严格的格式化器(gofmt 的超集),团队统一风格时常用。

示例
go install mvdan.cc/gofumpt@latest
gofumpt -extra -w .

注意gofumpt 的输出是 gofmt 兼容的更严格版本,混用两个工具格式化同一仓库会产生反复横跳的 diff。

staticcheck ./...

事实标准的深度静态检查,覆盖 bug、性能、弃用 API、代码简化建议。

示例
go install honnef.co/go/tools/cmd/staticcheck@latest
staticcheck ./...

注意和 go vet 是互补关系不是替代关系:vet 管编译级高置信问题,staticcheck 管更宽的最佳实践。

关键环境变量用 go env -w 写入的配置持久保存在 go env 文件里,对所有终端会话生效。

GOPROXY

模块下载代理。国内网络必配,否则拉github上的依赖经常超时。

示例
go env -w GOPROXY=https://goproxy.cn,direct
go env -w GOPROXY=https://goproxy.io,direct   # 另一个常用镜像

注意direct 要放在最后:意思是「所有代理都失败后才直连源仓库」;只写 direct 等于完全不用代理。

GOPRIVATE

声明私有模块路径前缀(glob),匹配的模块跳过代理和 sum 校验,直连仓库。

示例
go env -w GOPRIVATE=git.company.com/*,github.com/myorg/*
go env -w GONOPROXY=git.company.com/*   # 只想绕过代理时

注意GOPRIVATE 同时是 GONOPROXY 和 GONOSUMDB 的默认值;只想跳过其中一项就单独设置那两个变量。

GOFLAGS

给所有 go 命令追加默认旗标,比如全局启用 -mod=mod 或 -race。

示例
go env -w GOFLAGS=-mod=mod
go env -u GOFLAGS   # 删除设置

注意项目根目录有 vendor/ 且 go >= 1.14 时默认自动 -mod=vendor,此时 go get 的改动看起来「不生效」多半是这个原因。

GOPATH / GOMODCACHE / GOBIN

GOPATH 是工作区根;模块缓存在 $GOPATH/pkg/mod(即 GOMODCACHE);安装的二进制去 GOBIN。

示例
go env GOPATH GOMODCACHE GOBIN
go env -w GOBIN=$HOME/bin   # 自定义安装位置

注意go install 装了工具却提示 command not found,基本都是 GOBIN 不在 PATH 里。

CGO_ENABLED

是否启用 CGO。交叉编译和纯静态二进制时设为 0。

示例
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app ./cmd/app

注意关掉 CGO 后 net 的域名解析和 os/user 的用户查询会走纯 Go 实现,行为与 glibc 略有差异( Alpine 容器里反而更稳)。

GO111MODULE(历史变量)

Go 1.11–1.22 时代的模块模式开关,Go 1.23 起已被 go 命令彻底移除,无需再设置。

示例
go env GO111MODULE   # 当前版本会报:unknown go environment variable

注意老 CI 脚本里的 GO111MODULE=on 可以直接删掉;如果升级后脚本报错,就是它。

go.mod 指令速查go.mod 一共就这几个指令,搞懂 replace 和 retract 能解决 80% 的依赖纠纷。

module / go / toolchain

模块路径、语言版本下限、期望的工具链版本,go.mod 的头部三行。

示例
module github.com/you/proj

go 1.26

toolchain go1.27.1

注意Go 1.21 起 go 指令是硬下限:工具链比它老会直接拒绝构建,而不是「试试看」。

require

声明依赖及最低版本。// indirect 注释表示间接依赖(不直接被你的代码 import)。

示例
require (
	github.com/gin-gonic/gin v1.10.0
	golang.org/x/sys v0.24.0 // indirect
)

注意Go 1.27 起 go mod tidy 会自动把多个 require 块合并成「直接 + 间接」两块的标准结构,手工拆块没有意义。

replace

把某个模块替换成本地目录或 fork,调试依赖和临时打补丁的标配。

示例
replace github.com/foo/bar => ../bar

replace github.com/foo/bar v1.2.3 => github.com/you/bar v1.2.4-fix

注意replace 只在主模块生效:你发布的库被别人 import 时,你库里的 replace 会被完全忽略。

exclude

明确排除某个有问题的版本,go 命令会当它不存在。

示例
exclude github.com/foo/bar v1.2.3

注意exclude 同样只在主模块生效;已发布的库撤回版本应该用 retract 而不是 exclude。

retract

库作者撤回自己已发布的版本(发错版本号的后悔药),go get 会自动避开。

示例
retract (
	v1.2.0   // 误发了未完成的功能
	v1.1.9   // 安全问题,请升级到 v1.1.10
)

注意retract 不删版本(代理上仍在,仍可被显式指定),只是不再被 @latest 等查询选中。

交叉编译与版本管理Go 的交叉编译不需要目标平台的工具链,一对环境变量就够了。

GOOS / GOARCH

指定目标操作系统与架构,直接加在 go build 前面即可交叉编译。

示例
GOOS=linux   GOARCH=amd64 go build -o app-linux-amd64   ./cmd/app
GOOS=linux   GOARCH=arm64 go build -o app-linux-arm64   ./cmd/app
GOOS=windows GOARCH=amd64 go build -o app.exe           ./cmd/app
GOOS=darwin  GOARCH=arm64 go build -o app-darwin-arm64  ./cmd/app

注意用到 CGO 的依赖(sqlite3 驱动等)交叉编译会失败,需要目标平台的 C 工具链,或换纯 Go 实现(如 modernc.org/sqlite)。

go tool dist list

列出当前工具链支持的全部 GOOS/GOARCH 组合。

示例
go tool dist list
go tool dist list | grep linux

注意小众组合(如 linux/riscv64)不需要额外安装任何东西,能列出来就能编。

GOTOOLCHAIN

工具链选择策略:auto 按 go.mod 自动下载切换(默认),local 只用本机版本。

示例
go env GOTOOLCHAIN
go env -w GOTOOLCHAIN=local   # 禁止自动下载工具链

注意CI 镜像里建议显式设为 local 并预装正确版本,否则构建会现场下载工具链,慢且可能失败。

-trimpath -ldflags "-s -w"

发布构建三件套:去掉本机路径、符号表与调试信息,体积能小 20–30%。

示例
go build -trimpath -ldflags="-s -w" -o bin/app ./cmd/app

注意-s -w 之后 panic 堆栈里的行号仍在,但无法用 delve 做源码级调试;发布件才用,日常构建别加。

go version / go env

确认当前工具链版本与全部环境配置,排查环境问题第一步。

示例
go version
go env GOVERSION GOOS GOARCH GOPROXY
go env -json   # 机器可读的全量配置

注意go env 显示的是「生效值」,它可能来自系统环境变量、go env -w 文件或默认值三处之一。

Go 工具链命令速查表

这是一张可以全文搜索的 Go 工具链速查表,覆盖日常开发最高频的六组内容:构建与测试(go build / go test)、模块与依赖(go mod tidy / go get)、格式化工具(gofmt / goimports)、关键环境变量(GOPROXY / GOPRIVATE)、go.mod 指令(require / replace / retract)以及交叉编译与工具链管理。

每条目都给出可直接照抄的示例和真实踩坑点——比如 go test 的结果缓存为什么会让「改了环境变量却没重跑」、vendor 目录为什么会让 go get 看起来「不生效」、replace 为什么只在主模块生效。内容随 Go 版本演进维护,当前适用于 Go 1.27.x。

主要功能

使用步骤

  1. 在顶部搜索框输入命令名或关键词(如 tidy、代理、replace)即时过滤条目。
  2. 或点分类标签跳到对应分组:构建测试 / 依赖 / 格式化 / 环境变量 / go.mod / 交叉编译。
  3. 直接复制示例区的命令使用,注意栏会提醒什么情况下结果和预期不同。
  4. 需要在线格式化 HTML/CSS/JS/SQL 代码时用本站的代码格式化工具;gofmt 相关的深入对比见博客。

常见问题

gofmt 和 goimports 到底有什么区别?

gofmt 只管代码排版(缩进、对齐、空格),不会动 import;goimports 在 gofmt 的基础上自动补全和删除 import,并按「标准库 / 第三方」分组排序。两者对同一份代码的输出可以不同,CI 里建议统一用 goimports -l 检查。更完整的对比(含 CI 配置示例)见本站博客专题。

GOPROXY 在国内怎么配?

执行 go env -w GOPROXY=https://goproxy.cn,direct 即可。结尾的 direct 表示「所有代理都失败后回源仓库直连」,必须放在最后;私有仓库再配合 GOPRIVATE=git.company.com/* 跳过代理与校验。

go get 和 go install 有什么区别?

go get 只修改当前项目的 go.mod(添加/升级/降级依赖),不安装任何二进制;go install pkg@version 用来安装命令行工具到 GOBIN,且会忽略当前目录的 go.mod。想给项目加依赖用 go get,想装全局工具用 go install。

交叉编译需要装目标平台的工具链吗?

不需要。GOOS=linux GOARCH=arm64 go build 一对环境变量即可,go tool dist list 能列出全部支持的组合。唯一的例外是依赖 CGO 的库(如部分 sqlite 驱动),需要目标平台的 C 工具链或改用纯 Go 实现。

GO111MODULE 还需要设置吗?

不需要。它是 Go 1.11–1.22 时代的模块模式开关,Go 1.23 起已被 go 命令彻底移除,设置它没有效果;老 CI 脚本里的 GO111MODULE=on 可以直接删掉。

相关工具与阅读

问题反馈

本站是纯前端静态站,没有后端也没有账号系统,反馈走 GitHub Issues、讨论区或邮件。

粘贴到 issue 或邮件里能帮我更快定位问题,其中不含你输入的任何内容

其它:查看已有反馈 · 邮件反馈(无需 GitHub 账号):278975598@qq.com