2012-04-03 84 views
205

注意:这个问题与this one有关,但两年在Go历史上是很长一段时间。组织一个多文件Go项目

在开发过程中组织Go项目的标准方式是什么?

我的项目是一个包mypack,所以我想我把所有的.go文件放在一个mypack目录中。

但后来,我想在开发过程中,以测试它,所以我至少需要一个文件,宣布main包,这样我可以做go run trypack.go

我应如何组织呢?每次我想尝试一次时,我是否需要做go install mypack

+14

该简要截屏是真棒:http://www.youtube.com/watch?v=XCsL89YtqCs – Matt 2013-05-28 16:17:34

+0

[这](http://www.goinggo.net/2013/ 07/how-packages-work-in-go-language.html)是理解如何用软件包组织项目的另一个有用的链接。比官方更容易遵循如何写代码我想。 – IamNaN 2015-04-09 06:33:22

回答

151

我会建议在How to Write Go Code

它记录了双方如何构建你的项目在一个go build友好的方式,以及如何编写测试审查这一页。测试不需要使用main软件包进行cmd。他们可以简单地将TestX命名为函数作为每个包的一部分,然后go test将发现它们。

在您的问题中,该链接中建议的结构有点过时,现在随着Go 1的发布。您不再需要将pkg目录置于src之下。只有3个与spec相关的目录是你的GOPATH的根目录中的3个:bin,pkg,src。下面src时,可以简单地将你的项目mypack,这下都是你的。去的文件包括mypack_test.go然后

go build将建设成根级别PKG和仓。

所以你GOPATH可能是这样的:

~/projects/ 
    bin/ 
    pkg/ 
    src/ 
     mypack/ 
     foo.go 
     bar.go 
     mypack_test.go 

export GOPATH=$HOME/projects

$ go build mypack 
$ go test mypack 
+23

导出变量时使用$ HOME而不是〜。 – 2013-05-20 17:22:46

+4

为什么$ HOME在推荐变量时推荐〜? – 425nesp 2014-08-01 21:28:48

+7

因为〜不是一个变量,只是一个别名。 – Pih 2014-08-03 18:06:18

58

JDI有关于使用GOPATH正确的信息。我想补充一点,如果你打算有一个二进制文件,你可能想为目录增加一个额外的层次。

~/projects/src/ 
    myproj/ 
     mypack/ 
      lib.go 
      lib_test.go 
      ... 
     myapp/ 
      main.go 

运行go build myproj/mypack将建设mypack包与它一起的依赖 运行go build myproj/myapp将建设myapp二进制连同它的依赖这可能包括mypack库。

+0

当然,如果他确实有一个主要的cmd,这将是有意义的。看起来像他只是创建一个图书馆软件包。 – jdi 2012-04-03 03:27:00

3

将文件保存在同一个目录中,并在所有文件中使用package main

myproj/ 
    your-program/ 
     main.go 
     lib.go 

然后运行:

~/myproj/your-program$ go build && ./your-program 
+0

这是如何工作的?你的main.go需要成为主包。据推测lib.go是在一个不同的包中,那么go工具会抱怨你不能在一个文件夹中包含两个包。 – I82Much 2014-01-18 23:45:44

+1

@ I82Much OP询问如何将一个程序包(主程序)分成多个文件。在这种情况下,lib.go处于相同的包中。 – Gustav 2014-01-19 17:47:31

+0

啊谢谢澄清。 – I82Much 2014-01-20 01:44:27

46

我研究了一些围棋项目和有变化的公平位。您可以告诉谁来自C以及谁来自Java,因为前者转储的是main包中的项目根目录中的所有内容,后者倾向于将所有内容都放在src目录中。然而,两者都不是最佳的。每种方式都有后果,因为它们会影响导入路径以及其他人如何重用它

为了获得最佳效果,我制定了以下方法。

myproj/ 
    main/ 
    mypack.go 
    mypack.go 

哪里mypack.gopackage mypackmain/mypack.go是(显然)package main

如果您需要其他支持文件,您有两种选择。请将它们全部保留在根目录中,或将专用支持文件放在lib子目录中。例如。

myproj/ 
    main/ 
    mypack.go 
    myextras/ 
    someextra.go 
    mypack.go 
    mysupport.go 

或者

myproj.org/ 
    lib/ 
    mysupport.go 
    myextras/ 
     someextra.go 
    main/ 
    mypack.go 
    mypage.go 

仅将文件放在一个lib目录,如果他们不打算被另一个项目中导入。换句话说,如果他们是私有支持文件。这就是lib背后的想法 - 将公共和私有界面分开。

这样做会给你一个很好的导入路径,myproj.org/mypack重用其他项目中的代码。如果您使用lib,则内部支持文件将具有指示该文件的导入路径myproj.org/lib/mysupport

在构建项目时,请使用main/mypack,例如, go build main/mypack。如果您有多个可执行文件,您还可以将这些文件分开,并且不需要创建单独的项目。例如main/myfoo/myfoo.gomain/mybar/mybar.go

+12

Idomatic是为主包使用'cmd/nameOfMyExecutable'子目录(如果你有多个命令,只需要'cmd/...';参见'golang.org/x/tools/cmd';否则通常是交换它周围有'main.go'在顶层)。你使用'go install'的方式会创建一个“main”(或“main.exe”)可执行文件。此外,惯用方法是使用内部子目录作为程序包/程序内部的一个子程序包,它不打算在其他地方使用(预计未来版本的Go将强制任何人都不会导入完成的内部程序包这条路)。 – 2015-06-06 18:54:46

10

似乎有不被组织围棋项目的标准方法,但https://golang.org/doc/code.html指定一个最佳实践对于大多数项目。 JDI的答案是好的,但如果你使用的github或到位桶,你有更多的图书馆,以及,你应该创建以下结构:

~/projects/ 
bin/ 
pkg/ 
src/ 
    github.com/ 
    username/ 
     mypack/ 
      foo.go 
      bar.go 
      mypack_test.go 
     mylib/ 
      utillib.go 
      utillib_test.go 

通过做这种方式,你可以有一个单独的存储库MYLIB,可以是用于其他项目,可以通过“go get”进行检索。您的mypack项目可以使用“github.com/username/mylib”导入您的库。有关详细信息:

http://www.alexvictorchan.com/2014/11/06/go-project-structure/