go get 仅管理依赖并更新 go.mod/go.sum,不编译安装;go install 专用于构建并安装 cli 工具到 $gobin,不修改 go.mod,二者作用域不同,混用易致依赖错乱或命令不可用。

go get 管理依赖,go install 安装命令行工具——二者用途分离,混用会导致 go.mod 写错、二进制找不到、版本不一致等问题。
go get 只负责写入 go.mod,不再编译安装
Go 1.18 起,go get 默认等价于 go get -d:它只下载源码、更新 go.mod 和 go.sum,完全跳过编译和安装步骤。即使你运行 go get github.com/spf13/cobra@v1.8.0,也不会生成可执行文件,也不会影响当前项目的构建结果(除非该包被 import)。
- 如果你在模块目录中执行,它会把依赖写入
go.mod的require段,并校验哈希写入go.sum - 源码实际存放在全局模块缓存:
$GOPATH/pkg/mod/cache/download/或$GOPATH/pkg/mod/下的包名@版本目录 - 加
-u会升级依赖及其所有间接依赖到最新兼容版本;不加则只更新指定包(且仅当本地无该版本时才拉取) - 误用
go get安装 CLI 工具(如go get golang.org/x/tools/cmd/goimports)在 Go 1.21+ 会静默失败——命令没装上,goimports依然报command not found
go install 专用于构建并放置可执行文件
go install 不修改当前项目的 go.mod,它独立拉取指定包的源码、编译 main 函数、把二进制丢进 $GOBIN(默认为 $GOPATH/bin)。它甚至不要求你在模块目录里执行——随便切到 /tmp 都能装。
在 Go 中使用 google/wire 实现编译时依赖注入——wire.NewSet、wire.Build、wire.Bind(接口→实现)、wire.Struct、wire.Value、wire.Interface
- 必须带
@版本后缀,例如go install github.com/cosmtrek/air@v1.47.1;不带会报invalid version: unknown revision master - 如果
$GOBIN不在PATH中,装完也运行不了——Linux/macOS 需确认export PATH=$GOBIN:$PATH已生效,Windows 需检查系统环境变量 - 它不关心当前目录有没有
go.mod,也不读取项目里的replace或exclude规则——装的是“干净”的远程版本 - 想重装某个工具?直接再跑一遍
go install即可覆盖,无需先rm $GOBIN/xxx
常见错误:路径、版本、环境三重陷阱
很多人卡在“明明装了却找不到命令”,根本原因往往不是命令写错,而是路径或版本没对上。
-
go install装的是包路径下的cmd/xxx子目录(如果有),不是包根路径。例如要装db2struct,得用go install github.com/Shelnutt2/db2struct/cmd/db2struct@latest,而不是.../db2struct@latest -
@latest不等于最新 tag:它可能指向一个未打 tag 的 commit,尤其当仓库主分支有新提交但没发版时;稳妥做法是查 GitHub Release 页面,明确用@v1.2.3 -
go env GO111MODULE必须是on(Go 1.16+ 默认开启),否则go get可能退化到 GOPATH 模式,把代码下到$GOPATH/src,导致模块行为异常 - 执行
go install前,建议先go env GOBIN确认目标路径,再ls $(go env GOBIN)看是否已有同名旧二进制残留
真正容易被忽略的点是:这两个命令背后操作的「作用域」完全不同。go get 是项目级的依赖声明,影响整个模块的构建一致性;go install 是系统级的工具部署,和你的项目无关。把它们当成两个不同维度的操作,问题就清晰了。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










