Go项目推荐采用cmd/、internal/、pkg/等分层目录结构,遵循按功能分包、避免循环依赖等原则,强调小而专注的包设计和清晰的依赖隔离。

Go 项目目录结构没有强制标准,但社区普遍采用清晰、可维护、符合 Go 习惯的布局。核心原则是:按功能分包、避免循环依赖、主入口明确、测试就近放置、外部依赖隔离。
基础目录骨架(推荐)
一个典型且易扩展的 Go 项目结构如下:
-
cmd/:存放可执行命令(main 包),每个子目录对应一个二进制文件(如
cmd/myapp) - internal/:仅限本项目内部使用的包,禁止被外部 module 导入(Go 1.4+ 自动保护)
- pkg/:可被外部项目安全复用的公共包(有稳定 API、带文档和测试)
- api/ 或 proto/:API 定义(OpenAPI/Swagger)或 Protocol Buffers 文件
- configs/:配置文件(YAML/TOML/JSON)及加载逻辑
- scripts/:部署、生成、检查等辅助脚本(Shell/Makefile)
- go.mod 和 go.sum:模块定义与依赖锁定
包组织的关键实践
Go 强调“小而专注”的包设计。每个包应只做一件事,并通过命名体现职责:
- 包名用小写单数名词(
user,auth,cache),不加下划线或驼峰 - 接口定义优先放在使用者所在包(如
service包定义UserRepository接口),实现放在internal/repo中——实现依赖抽象,而非相反 - 避免在
internal/下嵌套过深(如internal/handler/v1/user),可扁平化为internal/user/handler或按层拆分(internal/user/service,internal/user/storage) - 测试文件与源码同目录(
user.go与user_test.go并列),使用子测试(t.Run)组织场景
初始化与模块管理
从零开始创建时,用标准命令初始化模块并设置版本:
立即学习“go语言免费学习笔记(深入)”;
- 运行
go mod init example.com/myproject生成go.mod - 在
cmd/myapp/main.go中写最简 main 函数,然后go run cmd/myapp验证构建通路 - 添加依赖时,直接在代码中 import 并运行
go build或go test,Go 会自动写入go.mod(无需手动go get) - 用
go mod tidy清理未使用依赖、补全间接依赖
常见误区与规避方式
新手容易陷入的结构陷阱:
-
所有代码堆在根目录 → 导致
main.go膨胀、无法复用、测试难写。解法:立即拆出internal/和pkg/ -
把数据库模型(struct)全塞进
models/目录 → 违反关注点分离。建议按领域组织:如internal/user包含该领域全部逻辑(DTO、domain struct、repository 接口、service) - 过度分包(每个函数一个包) → 增加导入复杂度。判断标准:能否独立测试?是否被多处复用?是否具备明确语义边界?
-
忽略
internal/与pkg/的语义差异 → 把未稳定、含业务细节的代码放pkg/,导致外部误依赖。记住:pkg/= “我承诺向你提供稳定契约”
不复杂但容易忽略:结构定型后,用 go list ./... 快速查看当前所有包路径,确认无冗余或错位;配合 IDE 的重构功能(如 VS Code + Go extension)可安全重命名包、移动文件并自动更新 import 路径。










