22

我对 Golang 目录结构有些困惑。

以<The way to go>一书为基础,将项目代码放入src,推荐如下目录结构。

    ├──src/
    |  ├──main.go
    |  ├──say/
    |  |  ├──say.go
    |  |  ├──say_test.go
    ├──bin/
    |  ├──say
    └──pkg/
       └──linux_amd64/
          └──say.a

但我发现很多包github.com,没有src目录。

例如:

https://github.com/facebookgo/grace

https://github.com/ataxie/beego

所以,我不知道是否src需要目录。

我有一些项目,它们相互依赖。它们在私有 GitLab 存储库中进行管理。

我该如何组织它们?

4

5 回答 5

22

当我开始使用 Go 时, Ben Johnson的这篇文章指导了我。

从这样的事情开始通常是好的(假设你在你的项目目录中,比如$GOPATH/src/myproject

├──cmd/ -- this is where you compose several packages in to main package
|  ├──foo -- an example would be `foo`
|  |  ├──main.go
├──pkg/ -- this is where put your reusable packages 
|  ├──pkg1 -- reusable package 1
|  ├──pkg2 -- reusable package 2
├──otherpackage1
|  ├── ...
├──otherpackage2
|  ├── ...

对于这种项目结构,您可以查看示例。go-kit

有时这取决于您的需求。在我们的工作流程中,我们使用了一个名为fresh的热代码重载工具,因此我们需要将 放在main.go项目根目录中,以便该工具可以检测所有文件更改并重建源代码。

├──app/
|  ├──app.go
├──model/ -- 
|  ├──model.go
├──store
|  ├──store.go
├──main.go -- this is where the app starts
├──...

app.go包装上,我有类似func Run() error启动应用程序的东西。在 上main.go,我只是调用函数:

...
func main(){
    log.Fatal(app.Run())
}
于 2017-10-10T09:40:59.680 回答
8

现在有组织golang项目的新方法。进入golang-standards的 github,上面写着:

这是 Go 应用程序项目的基本布局。它代表了最常见的目录结构,具有许多小的增强功能,以及任何现实世界应用程序共有的几个支持目录。

这个项目布局是故意通用的,它不会尝试强加特定的 Go 包结构。

或者您可以按照以下幻灯片进行操作:

$GOPATH/
    src/
        github.com/user/repo/
            mypkg/
                mysrc1.go
                mysrc2.go
            cmd/mycmd/
                main.go
    bin/
        mycmd
于 2018-04-09T11:59:08.810 回答
2

src 目录不是必需的,事实上很多公共存储库不使用这种结构。

有几种不同的方式来组织你的项目。如果您打算让其他存储库使用您的项目,例如 lib. 我建议使用类似这样的 cmd 结构。如果启动应用程序的方式不止一种,这也是推荐的方式。(可乘的 main.go 文件)

├──cmd/
|  ├──(application name)
|  |  ├──main.go
└──say/
   ├──say.go
   └──say_test.go

否则,例如,如果它是一个独立的应用程序。您可以将 main.go 放在存储库的根目录中。

bin 和 pkg 您可以保留在根目录中并将其添加到 .gitignore。(假设您使用的是 git)

于 2017-10-09T12:51:56.660 回答
2

该书描述了结帐后的目录结构。如果这本书包含 .git 目录会很有帮助。

导入工作需要 $GOPATH/src。

    ├──src/
    |  ├──.git
    |  |  ├──...
    |  ├──main.go
    |  ├──say/
    |  |  ├──say.go
    |  |  ├──say_test.go
    ├──bin/
    |  ├──say
    └──pkg/
       └──linux_amd64/
          └──say.a

实际上,main.go 实际上会位于反映远程 git 存储库的路径中,例如

.   
├── bin
│   └── say
├── pkg
│   └── linux_amd64
│       └── github.com
│           └── pschultz
│               └── hello-world
│                   └── say.a
└── src
    └── github.com
        └── pschultz
            └── hello-world
                ├── .git
                │   └── ...
                ├── main.go
                └── say
                    ├── say.go
                    └── say_test.go
于 2017-10-09T16:13:23.017 回答
1

这是另一个项目布局示例Simple Go 项目布局与模块

├── LICENSE
├── README.md
├── config.go
├── go.mod
├── go.sum
├── clientlib
│   ├── lib.go
│   └── lib_test.go
├── cmd
│   ├── modlib-client
│   │   └── main.go
│   └── modlib-server
│       └── main.go
├── internal
│   └── auth
│       ├── auth.go
│       └── auth_test.go
└── serverlib
    └── lib.go

一些答案指出了标准布局,但是,有一个问题,这不是Russ Cox的标准 Go 项目布局

这个 GitHub 存储库有两个问题:

  • 它声称拥有 Go 标准,但实际上并没有,因为这些绝不是官方标准
  • 它提出的项目布局标准过于复杂而不是标准

关于“为什么不告诉我们标准的 Go 项目布局,我们会更新文档?”,这仅涉及第 2 点。如果真的有标准,它们将在主要的 Go 项目文档树中。项目布局的标准也会短很多。我感谢您尝试提供有用的资源,但称其为“golang-standards”的要求比实际要多。

但是为了记录,可导入的 Go 存储库的最小标准布局实际上是:

  • 将 LICENSE 文件放在您的根目录中
  • 将 go.mod 文件放在您的根目录中
  • 将 Go 代码放入您的存储库、根目录或组织成您认为合适的目录树

而已。这就是“标准”。


2021 年 11 月 30 日更新

以下是如何构建 Go 代码的摘要

  • 在我们开始之前
    • doc.go文件放置包的一般描述
    • Readme提交该项目的一般概述
    • 当您有更多文档要提供时,将它们放入docs文件夹中
    • 对于 linting 使用 golangci-lint。启用对您的项目似乎合理的所有 linter
  • 扁平结构(单包)
    courses/
      main.go
      server.go
      user_profile.go
      lesson.go
      course.go
    
    • 何时创建新包?
      • 当您有不止一种启动应用程序的方式时
      • 当你想提取更详细的实现时
      • 当您开始为密切相关的事物添加通用前缀时
  • 模块化
    • 按种类组织
.
├── handlers
│   ├── course.go
│   ├── lecture.go
│   ├── profile.go
│   └── user.go
├── main.go
├── models
│   ├── course.go
│   ├── lecture.go
│   └── user.go
├── repositories
│   ├── course.go
│   ├── lecture.go
│   └── user.go
├── services
│   ├── course.go
│   └── user.go
└── utils
    └── stings.go
  • 按组件组织
.
├── course
│   ├── httphandler.go
│   ├── model.go
│   ├── repository.go
│   └── service.go
├── main.go
└── profile
    ├── httphandler.go
    ├── model.go
    ├── repository.go
    └── service.go
  • 清洁架构
    • 您的应用程序或模块有 4 层(取决于您的代码库有多大):域、应用程序、端口、适配器。在某些来源中,名称可能不同。
于 2021-05-06T09:39:38.250 回答