如何使用Golang初始化新项目_快速生成基础目录结构

go mod init 仅创建 go.mod 文件,不生成目录或骨架代码;需手动构建标准分层结构:cmd/放主入口、internal/放私有逻辑、pkg/放可复用组件,确保可测试性与可维护性。

go mod init 初始化模块是起点,但不等于项目结构

很多人执行 go mod init myapp 后就以为项目建好了,其实这只创建了 go.mod 文件,没生成任何目录或骨架代码。Go 官方不内置项目脚手架,必须手动补全或借助工具。

常见错误是直接在根目录写 main.go 然后一路平铺,等加到 5 个包时才发现 import 路径混乱、测试难组织、构建产物污染源码。

  • 推荐从一开始就按标准分层:比如 cmd/ 放主程序入口,internal/ 放私有逻辑,pkg/ 放可复用组件
  • cmd/myapp/main.go 只负责解析 flag、初始化依赖、调用核心函数,业务逻辑全下沉
  • 避免把所有东西塞进 main.go —— 这会让单元测试无法 import 主逻辑

手动创建最小可用结构(无外部依赖)

不需要装任何工具也能快速搭出可持续演进的结构。以下是最小但合理的布局:

myapp/
├── go.mod
├── cmd/
│   └── myapp/
│       └── main.go
├── internal/
│   └── app/
│       ├── app.go
│       └── app_test.go
└── pkg/
    └── version/
        └── version.go

关键点:

  • go mod init myapp 必须在项目根目录运行,模块名建议用最终部署的域名路径(如 github.com/user/myapp),方便后期发布到 GOPROXY
  • cmd/myapp/main.goimport 必须引用 "myapp/internal/app",不能写相对路径
  • internal/ 下的包默认不可被外部 module import,适合放业务核心;pkg/ 则显式设计为可导出

curl + bash 一键生成结构(适合 CI 或批量初始化)

如果频繁新建项目,可以写个极简脚本避免重复劳动。下面这个命令能自动创建上述结构(Linux/macOS):

mkdir -p myapp/{cmd/myapp,internal/app,pkg/version} && \
cd myapp && \
go mod init myapp && \
touch cmd/myapp/main.go internal/app/app.go internal/app/app_test.go pkg/version/version.go

注意几个易错细节:

  • 不要在 cmd/ 目录下执行 go mod init,否则模块名会变成 cmd/myapp,后续 import 全错
  • 生成的 main.go 需手动填入最简启动逻辑,例如:
    package main
    
    import (
    	"log"
    	"myapp/internal/app"
    )
    
    func main() {
    	if err := app.Run(); err != nil {
    		log.Fatal(err)
    	}
    }
  • 如果用 VS Code,记得在打开项目前先 cd myapp,否则 Go 扩展可能识别不到 module 根

为什么不用 go-kitkratos 这类框架?

它们确实带完整目录和模板,但代价是强约束和隐式约定。比如 kratos new myapp 会强制你接受 protobuf + gRPC + config center 三层结构,哪怕你只是写个 CLI 工具。

真正需要警惕的是“过早抽象”:一个只有 3 个 HTTP handler 的服务,没必要一上来就拆 data/biz/service/ 三层。先跑通 cmd → internal → pkg 三级就足够清晰。

复杂点往往不在结构本身,而在于什么时候该把 internal/app 拆成 internal/handlerinternal/service —— 这取决于接口变更频率和测试隔离需求,不是靠模板能预判的。