布局Go项目的合理方法是什么?

时间:2013-02-14 03:43:09

标签: go project

我的go项目开始变得更加复杂,并希望以减轻痛苦的方式放置文件系统。

有什么有意义的好例子吗?

3 个答案:

答案 0 :(得分:121)

2013年5月更新:官方文档位于" Code organization"

部分
  

Go代码必须保存在工作区中   工作空间是一个目录层次结构,其根目录有三个目录:

  • src包含组织到包中的Go源文件(每个目录一个包),
  • pkg包含包对象,
  • bin包含可执行命令。
  

go tool构建源包并将生成的二进制文件安装到pkgbin目录。

     

src子目录通常包含多个版本控制存储库(例如Git或Mercurial),用于跟踪一个或多个源包的开发。

bin/
    streak                         # command executable
    todo                           # command executable
pkg/
    linux_amd64/
        code.google.com/p/goauth2/
            oauth.a                # package object
        github.com/nf/todo/
            task.a                 # package object
src/
    code.google.com/p/goauth2/
        .hg/                       # mercurial repository metadata
        oauth/
            oauth.go               # package source
            oauth_test.go          # test source

2014年7月更新:请参阅" Structuring Applications in Go"来自Ben Johnson

该文章包括以下提示:

将二进制文件与应用程序分开

  

main.go文件和我的应用程序逻辑组合在同一个包中有两个结果:

     
      
  • 它使我的应用程序无法用作库。
  •   
  • 我只能有一个应用程序二进制文件。
  •   
     

我发现修复此问题的最佳方法是在我的项目中使用“cmd”目录,其中每个子目录都是应用程序二进制文件。

camlistore/
  cmd/
    camget/
      main.go
    cammount/
      main.go
    camput/
      main.go
    camtool/
      main.go

图书馆驱动开发

  

main.go文件移出根目录,可以从库的角度构建应用程序。您的应用程序二进制文件只是应用程序库的客户端。

     

有时您可能希望用户以多种方式进行交互,因此您可以创建多个二进制文件   例如,如果您有一个允许用户一起添加数字的“adder”包,您可能希望发布命令行版本以及Web版本。
  您可以通过以下方式组织项目来轻松完成此任务:

adder/
  adder.go
  cmd/
    adder/
      main.go
    adder-server/
      main.go
  

用户可以使用省略号“go get”安装“adder”应用程序二进制文件:

$ go get github.com/benbjohnson/adder/...
  

瞧,您的用户安装了“adder”和“adder-server”!

不要对子包

发疯
  

通常我的项目类型都非常相关,因此从可用性和API的角度来看,它更适合   这些类型还可以利用它们之间的未管理调用,从而使API保持小而清晰。

     
      
  1. 在每个文件中将相关类型和代码组合在一起。如果您的类型和功能组织良好,那么我发现文件往往介于200到500 SLOC之间。这可能听起来很多,但我觉得很容易导航。 1000 SLOC通常是单个文件的上限。
  2.   
  3. 在文件顶部组织最重要的类型,并在文件底部添加重要性递减的类型。
  4.   
  5. 一旦您的应用程序开始超过10,000 SLOC,您应该认真评估它是否可以分解为更小的项目。
  6.   

注意:最后一次练习并不总是好的:

  

对不起,我不能同意这种做法   将类型分隔为文件有助于代码管理,可读性,可维护性,可测试性   它也可以确保单一责任和遵循开放/封闭原则......
  不允许循环依赖的规则是强制我们有一个清晰的包结构。


(2013年2月替代,仅针对src
您可以找到" GitHub Code Layout":

中说明的经典布局
  

应用程序和两个库都存放在Github上,每个库都在自己的存储库中   $GOPATH是项目的根目录 - 您的每个Github存储库都会在$GOPATH下面的几个文件夹中签出。

     

您的代码布局如下所示:

$GOPATH/
    src/
        github.com/
            jmcvetta/
                useless/
                    .git/
                    useless.go
                    useless_test.go
                    README.md
                uselessd/
                    .git/
                    uselessd.go
                    uselessd_test.go
                    README.md
  

src/github.com/jmcvetta/下的每个文件夹都是单独的git checkout的根目录。

但是,这引起了一些批评:reddit page

  

我强烈建议不要按照你的方式构建回购,它会打破" go get",这是关于Go最有用的事情之一。
  为知道Go的人编写代码要好得多,因为他们最有可能是编译它的人。   对于那些不熟悉的人,他们至少会对这种语言有所了解。

     

将主包放在回购的根目录中   将资产放在子目录中(以保持整洁)   将代码的内容保存在子包中(如果有人想在二进制文件之外重用它)   在repo的根目录中包含一个设置脚本,以便于查找。

     

下载,构建,安装和设置仍然只需两个步骤:

     
      
  • &#34; go get <your repo path>&#34;:下载并安装go代码,以及资产的子目录
  •   
  • $GOPATH/<your repo path>/setup.sh:将资产分发到正确的位置并安装服务
  •   

答案 1 :(得分:7)

我认为,对于'project',你不是指Go包,而是你开发的软件。 否则,您可以获得帮助herehere。 然而,为Go编写软件包并没有太大的不同:使用软件包,为每个软件包创建一个文件夹,并在应用程序中组合这些软件包。

为了建立自己的观点,你可以在github上查看热门Go存储库:https://github.com/trending/go。值得注意的例子是cayleyzeus

最流行的方案可能是在自己的目录中有一个主Go文件和许多模块和子模块。如果您有许多元文件(doc,license,templates,...),您可能希望将源代码放入子目录中。这就是我到目前为止所做的。

答案 2 :(得分:1)

Golang的作者有一个recommended approach定义了如何布局代码以便最好地使用go工具并支持源代码控制系统