go build ./...
编译当前模块的所有包。不带 -o 时只检查能否编译,不会留下二进制文件。
go build -o bin/app ./cmd/app
注意./... 不会包含 vendor 目录和子模块(各有自己 go.mod 的目录)。
覆盖 go build/test、go mod 依赖管理、gofmt/goimports、环境变量、go.mod 指令与交叉编译,每条附可直接照抄的示例和真实踩坑点
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 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 -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 管更宽的最佳实践。
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 可以直接删掉;如果升级后脚本报错,就是它。
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 等查询选中。
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 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。
gofmt 只管代码排版(缩进、对齐、空格),不会动 import;goimports 在 gofmt 的基础上自动补全和删除 import,并按「标准库 / 第三方」分组排序。两者对同一份代码的输出可以不同,CI 里建议统一用 goimports -l 检查。更完整的对比(含 CI 配置示例)见本站博客专题。
执行 go env -w GOPROXY=https://goproxy.cn,direct 即可。结尾的 direct 表示「所有代理都失败后回源仓库直连」,必须放在最后;私有仓库再配合 GOPRIVATE=git.company.com/* 跳过代理与校验。
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 实现。
不需要。它是 Go 1.11–1.22 时代的模块模式开关,Go 1.23 起已被 go 命令彻底移除,设置它没有效果;老 CI 脚本里的 GO111MODULE=on 可以直接删掉。