go mod init 是创建新模块的唯一标准入口,必须在空目录或仅含源码文件的目录中执行,模块路径需为全局唯一可解析的导入前缀(如 github.com/username/project),不可随意填写;它不下载依赖,仅生成基础 go.mod,后续 go build 或 go mod tidy 才触发依赖分析与填充。
Go 1.11 引入模块(module)后,go mod init 是创建新模块的唯一标准入口,不是可选步骤,而是构建可复现依赖的前提。跳过它或随意填写模块名,后续 go build、go test 都可能静默降级为 GOPATH 模式,导致依赖解析异常。
模块路径(即 go mod init 后跟的参数)本质是导入路径前缀,不是项目名也不是文件夹名。它应反映代码未来被他人 import 时的真实路径。
github.com/username/project,即使本地未 push 也应如此设定example.com 或 myproject 这类无意义占位符——它们会导致 go get 失败,且无法被其他模块正确引用git.internal.company/project),并配合 GOINSECURE 或私有代理配置go mod init 会扫描当前目录下所有 .go 文件,自动推导依赖并写入 go.mod。如果目录里混有旧的 Gopkg.lock、vendor/ 或已编译二进制,不会报错,但可能漏掉间接依赖或误判主模块路径。
rm -rf vendor/ Gopkg.lock go.sum(如有)go.mod 不存在,否则 go mod init 会直接报错 go.mod already exists
go.mod 但想重置,需先删除再重新 init,不能靠覆盖
执行 go mod init example.com/foo 只生成最简 go.mod,内容类似:
module example.com/foo go 1.21
此时运行 go build 才会触发依赖分析,并自动生成 go.sum 和填充 require 条目。常见误解是认为 init 会拉取包——它不会。
"golang.org/x/sync/errgroup"),首次 go build 会失败并提示 “missing go.sum entry”,这是正常流程go mod tidy,而不是反复调用 initgo mod init 自动设为当前 go version 输出的主版本(如 go1.21),不可手动指定小版本一个文件夹下只能有一个 go.mod。若你在 cmd/app/ 和 internal/pkg/ 分别运行 go mod init,Go 会把后者识别为独立模块——但实际它们属于同一代码库,这种拆分会导致版本不一致、测试失败、replace 难以维护。
go mod init github.com/user/repo
github.com/user/repo/internal/pkg
github.com/user/repo/v2)时,才在子目录新建模块并 init最容易被忽略的是模块路径和实际 Git 仓库地址的对齐。CI 构建、Go Proxy 缓存、甚至 go list -m all 的输出,都依赖这个路径的真实性。随便写个名字,短期能跑,长期会让协作和升级变成黑洞。