模块名必须与未来实际导入路径一致,如打算用 import "github.com/yourname/myapp/utils",则需执行 go mod init github.com/yourname/myapp,不可用本地路径、短名或拼写错误。
直接在项目根目录执行 go mod init 即可初始化模块,但模块名必须与未来代码实际导入路径一致,否则后续 import 会失败或引发循环依赖。
模块名不是随便起的,它等价于你将来在其他地方 import 这个项目的路径前缀。比如你打算让别人用 import "github.com/yourname/myapp/utils",那初始化时就必须写:
go mod init github.com/yourname/myapp
常见错误包括:
go mod init ./myapp(Go 不支持)go mod init myapp(会导致 import 路径不匹配,go build 报 cannot find module providing package)go get 会拉错版本)Go 官方不强制结构,但社区共识是按功能分层,避免把所有文件塞进根目录。典型结构如下:
myapp/
├── go.mod
├── main.go
├── cmd/
│ └── myapp/
│ └── main.go
├── internal/
│ └── service/
│ └── user.go
├── pkg/
│ └── utils/
│ └── helper.go
└── api/
└── v1/
└── handler.go
关键点:
cmd/ 下放可执行入口,每个子目录对应一个二进制(利于多命令项目,如 cmd/server 和 cmd/cli)internal/ 仅限本模块内部使用,外部无法 import(Go 编译器强制保护)pkg/ 是有意暴露给外部复用的公共包(命名需稳定,API 变更需考虑语义化版本)main.go 应极简,只做 cmd/myapp/main.go 的符号链接或弃用,避免混淆构建入口初始化只是起点,不补全这三项,后续开发大概率卡住:
go mod tidy:自动补全依赖、清理未使用项,并生成 go.sum
go.mod 中 go 版本是否匹配本地 go version;若不一致(如写 go 1.20 但本地是 1.22),建议显式升级:go mod edit -go=1.22
GOPROXY 设置
合理,国内推荐:export GOPROXY=https://goproxy.cn,direct,否则 go get 可能超时或 404模块名一旦写进 go.mod,就决定了整个项目的 import 路径契约;改名不是改一行那么简单,得同步更新所有 import 语句、CI 脚本里的路径、文档示例,甚至已发布的 tag。一开始想清楚再敲下 go mod init。