Go包名必须全小写、无下划线或驼峰,与目录名严格一致,避免泛化名如utils,导入路径与包名协同设计,且对外暴露后不可更改。

包名必须全小写且不能含下划线或驼峰
Go 官方明确不鼓励、社区几乎从不使用 _ 或大小混写(如 myPackage、user_auth),因为这会破坏工具链兼容性(比如某些文件系统区分大小写)、增加拼写错误风险,也违背标准库一贯风格。你看到的 fmt、net/http、encoding/json 全是纯小写单词或路径段。
- ✅ 正确:
cache、auth、strutil、httpclient - ❌ 错误:
Cache、user_utils、HTTPClient、json_parser - ⚠️ 注意:
http是合法包名,尽管它是缩写——Go 接受常见英文缩略词,但不接受自造缩写如usr(应写user)
包名必须与目录名严格一致
这不是语法强制,但 Go 工具链(go build、go test、IDE 跳转)和所有主流 CI/CD 流程都默认依赖这一约定。一旦不一致,就会出现“找不到包”“测试无法运行”“VS Code 提示未解析导入”等隐性问题。
- 目录结构是
myproject/auth/→ 文件开头必须是package auth - 目录结构是
internal/cache/redis/→ 包名必须是redis,不是cache_redis或rediscache - 如果你硬写成
package authz在auth/目录下,go list ./auth仍能识别,但其他开发者和自动化脚本大概率失效
避免泛化包名如 utils、common、helpers
这类名字不表达职责,导致包边界模糊、功能堆积、后期难以拆分。Go 强调“一个包一个职责”,命名就是第一道契约。
- ❌ 不要建一个叫
utils的目录,把字符串、时间、加密函数全塞进去 - ✅ 拆成语义明确的包:
strutil(字符串操作)、timeutil(时间格式转换)、crypto(加解密逻辑) - ⚠️ 特例:
errors是标准库包名,但它承载的是 Go 错误处理的核心抽象,不是“随便放点工具函数”的容器 —— 别拿它当借口
导入路径 ≠ 包名,但两者必须协同设计
导入路径(如 "myproject/auth")由 go.mod 的 module 声明决定,而包名只是该路径最后一段。混淆这两者是新人最常踩的坑:以为改了目录就能改导入路径,或以为改了包名就能解决冲突。
立即学习“go语言免费学习笔记(深入)”;
- 你的
go.mod是module github.com/you/app,那么auth/目录下的包,导入路径就是"github.com/you/app/auth",包名仍是auth - 如果两个包都想叫
config(比如auth/config.go和database/config.go),别试图改成authconfig和dbconfig—— 应保持包名都是config,靠不同导入路径自然隔离 - 真遇到命名冲突(比如你要用
github.com/someone/log,但本地也有log包),用导入别名:import mylog "github.com/someone/log",而不是改自己包名
最易被忽略的一点:包名一旦对外暴露(比如发布为公共模块),就基本不可更改——改名等于破坏所有下游导入。所以从第一个 go mod init 开始,就该按规范定好每个子目录的包名,别留到“以后再重构”。










