main.go应放在模块根目录(单命令)或cmd/{name}/下(多命令),不可置于internal/或pkg/;go.mod必须在模块根目录以正确定义import路径;测试文件须与源码同目录同包且命名xxx_test.go。

main.go 放哪?别猜,看 go build 怎么找
go build 默认只在当前目录找 main.go,且它必须属于 main 包。如果你把它塞进 cmd/myapp/,go run . 就会报 no Go files in current directory——不是代码错了,是路径没对上。
- 单命令项目:直接放模块根目录,
go run .和go build都能立刻执行 - 多命令项目(如 CLI + server):用
cmd/{name}/main.go,每个main.go独立成包,运行时显式指定路径,比如go run cmd/myapp-cli/main.go - 别把
main.go放进internal/或pkg/:Go 编译器不认这些目录下的main包,静默跳过,不报错也不构建
go.mod 在哪?它定义了整个项目的“国界”
go.mod 所在目录就是模块根,也是所有 import 路径的起点。路径不匹配,IDE 找不到符号、go test 加载失败、go mod tidy 会漏依赖——全是静默问题,很难定位。
- 一个项目只应有一个
go.mod,放在 Git 仓库根目录最稳妥 - 错误示范:
myproject/api/v1/handler.go里写import "myproject/internal/db",但go.mod在myproject/api/下 → Go 认为模块名是myproject/api,根本解析不了myproject/internal/db - 子模块要独立发布?拆成新仓库 + 新
go.mod,别靠嵌套目录假装模块化
internal/ 和 pkg/ 到底怎么分?编译器只认 internal
internal/ 是 Go 原生支持的访问控制机制;pkg/ 只是社区旧习惯,没有语言级约束。滥用 pkg/ 容易让外部项目误引未发布代码,版本混乱。
-
internal/下的包(如internal/auth)被外部模块import时,go build直接报错:use of internal package not allowed -
pkg/没有导入限制,但若你没把它发布为独立模块,别人import "your-repo/pkg/utils"实际走的是相对路径或replace,CI 构建可能拉错版本 - 判断标准很简单:这段逻辑确定只给本项目用?→ 放
internal/;打算开源复用、有明确 API 和版本管理?→ 单独建仓库,别塞进主项目
测试文件为什么总被忽略?命名和位置缺一不可
Go 测试不是靠目录名识别的,只认两件事:*_test.go 文件名 + 和被测代码同目录同包。漏掉任一条件,go test 就静默跳过,不报错也不运行。
- 必须叫
xxx_test.go,test_xxx.go或xxx_test.go.bak都无效 - 必须和源码在同一个目录,比如
storage/db.go的测试得放在storage/db_test.go,不能挪到test/storage/db_test.go - 必须属于同一个包名,
storage/db.go是package storage,那db_test.go开头也得是package storage(不是package storage_test)
go.mod 位置和 import 路径之间的刚性绑定——它不像其他语言的配置可以“大概对”,差一级目录,整个依赖图就断了,而且往往不报错,只在某个 CI 环境或别人 clone 后才暴露。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











