很多的时候,咱们开发一个简略的Go我的项目的时候并不需要纠结于我的项目的的目录布局,因为咱们会将所有go源码文件扔在我的项目的根目录中,就像上面这样:

demo
├── main.go
├── model.go
└── service.go

但当咱们的我的项目变得复杂的时候,咱们就须要好好思考怎么组织咱们的我的项目了,这时候你可能会想,用官网的Go我的项目目录布局就好了,然而Go的官网并没有给出一个规范的Go我的项目规范目录布局。

目前,Go社区开发者比拟举荐的是project-layout我的项目中给出的目录布局,如:

demo
├── api
├── assets
├── build
├── cmd
├── configs
├── deployments
├── docs
├── examples
├── githooks
├── init
├── internal
├── pkg
├── scripts
├── test
├── third_party
├── tools
├── vendor
├── web
└── website

然而官网并不举荐这种我的项目布局形式,上面是Go团队开发leader Russ Cox对project-layout目录的意见:

大体上,咱们能够将Go的我的项目分为两类,利用我的项目与库我的项目。

  • 利用我的项目:即蕴含可执行文件的我的项目,我的项目开发后,须要编译成可执行文件并上线运行。
  • 库我的项目:库文件个别用于裸露Api,被其余我的项目通过import关键字引入。

利用我的项目与库我的项目的目录布局形式稍有差别。

利用我的项目

对于利用我的项目,其目录布局形式咱们能够参考Go我的项目本身,以及一些应用Go语言开发的优良开源我的项目(如Docker,Kubernetes,etcd)等,通过钻研这些我的项目的目录布局,咱们能够形象出以下规范目录:

demo
├── cmd
│   ├── app1
│   │   └── main.go
│   └── app2
│       └── main.go
├── go.mod
├── go.sum
├── internal
│   ├── pkga
│   │   └── pkg_a.go
│   └── pkgb
│       └── pkg_b.go
├── pkg1
│   └── pkg1.go
├── pkg2
│   └── pkg2.go
└── vendor

cmd

可执行文件目录,如果一个我的项目有多个可执行文件,能够放在不同的子目录中,如下面例子中的app1和app2目录。

internal

我的项目外部公有代码,其余我的项目引入时会报错。

pkgN:

留神,这里并不是说肯定要pkg为前缀来命名,你能够对取任意合乎包命名标准的名称,比方service,model等

即下面示例中的pkg1与pkg2,pkgN包与internal包一样寄存我的项目的依赖代码,但存储在这里的代码,能够被其我的项目引入。

vendor

这个目录用于存储我的项目的依赖包,但因为现今Go我的项目都是应用go module进行依赖治理,因而这个目录是可省略的。

如果咱们的我的项目只有一个可执行文件,能够将main.go文件间接写在根目录,而vendor能够省略,因而,我的项目目录能够进一步精简为:

demo
├── go.mod
├── go.sum
├── internal
│   ├── pkga
│   │   └── pkg_a.go
│   └── pkgb
│       └── pkg_b.go
├── main.go
├── pkg1
│   └── pkg1.go
└── pkg2
    └── pkg2.go

库我的项目

库我的项目不须要可执行文件,相比于利用我的项目,省略了cmd目录,其规范目录下:

demo
├── go.mod
├── go.sum
├── internal
│   ├── pkga
│   │   └── pkg_a.go
│   └── pkgb
│       └── pkg_b.go
├── pkg1
│   └── pkg1.go
└── pkg2
    └── pkg2.go

如果咱们的库我的项目比较简单,能够采纳平铺式我的项目布局,行将所有的性能写在一个包里,所有源码目录放在根目录下,如:

demo
├── feature1.go
├── feature2.go
├── feature3.go
├── go.mod
└── go.sum

平铺式的我的项目布局非常适合简略的库我的项目,事实上,很多简单的库我的项目也会将大量的代码放在根目录下,因为这样,其余我的项目应用import引入我的项目的包时,门路会比拟短,比方咱们有一个构造体A,放在pkg1包下与放在根目录下,其引门路别离是:

import "demo"

import "demo/pkg1"

小结

好了,浏览到这里,想必你曾经理解了Go利用我的项目与库我的项目目录布局的不同了吧。

不过,因为Go官网我的项目指定的我的项目布局,因而上述的几种我的项目目录都是社区开发的约定俗成,并不具备强制性,你也能够定制本人的Go我的项目目录布局,不过我想,应用社区开发都遵循的目录标准,还是有助于升高团队开发人员的认知与交换老本的。