组织一个多文件Go项目

Bla*_*sad 233 go

注意:这个问题涉及到这一块,但两年是围棋历史很长一段时间.

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

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

但是,我想在开发过程中测试它,所以我至少需要一个声明main包的文件,这样我才能做到go run trypack.go

我该如何组织这个?go install mypack每次我想尝试时都需要做吗?

jdi*_*jdi 169

我建议在如何编写Go Code上查看此页面

它记录了如何以go build友好的方式构建项目,以及如何编写测试.测试不需要是使用main包的cmd .它们可以简单地将TestX命名函数作为每个包的一部分,然后go test将发现它们.

在您的问题中该链接中建议的结构有点过时,现在随着Go 1的发布.您不再需要在其pkg下放置目录src.只有3个与规范相关的目录是GOPATH根目录中的3个:bin,pkg,src.在src下面,您可以简单地放置您的项目mypack,并在其下面是您的所有.go文件,包括mypack_test.go

go build 然后将构建到根级别pkg和bin.

所以你的GOPATH可能看起来像这样:

~/projects/
    bin/
    pkg/
    src/
      mypack/
        foo.go
        bar.go
        mypack_test.go
Run Code Online (Sandbox Code Playgroud)

export GOPATH=$HOME/projects

$ go build mypack
$ go test mypack
Run Code Online (Sandbox Code Playgroud)

  • 导出变量时使用$ HOME而不是〜. (25认同)
  • 因为〜不是变量,只是别名. (8认同)
  • 为什么在导出变量时$ HOME被推荐? (6认同)
  • @ 425nesp Johan错了 - 事实并非如此.shell有所不同,但是[bash在设置环境变量时会扩展`~`](https://www.gnu.org/software/bash/manual/html_node/Tilde-Expansion.html),busybox bourne shell也是如此.实例.自己试试:`export BOB =〜&& env | grep ^ BOB`将产生`BOB =/your/homedir` (6认同)
  • `$HOME` 可以在更多的 shell 中使用,然后是 `~`,例如在 `fish` (3认同)

Jer*_*all 60

jdi有关于使用的正确信息GOPATH.我想补充一点,如果您打算使用二进制文件,您可能需要在目录中添加一个额外的级别.

~/projects/src/
    myproj/
        mypack/
            lib.go
            lib_test.go
            ...
        myapp/
            main.go
Run Code Online (Sandbox Code Playgroud)

运行go build myproj/mypack将构建mypack包及其运行的依赖项go build myproj/myapp将构建myapp二进制文件及其依赖项,其中可能包括mypack库.


tra*_*ans 48

我研究了许多围棋项目,并且有一些变化.你可以种知道谁是由C来了,谁是从Java的到来,因为前者转储只是在一切都在项目的根目录main软件包,而后者往往把一切都放在一个src目录.然而,两者都不是最佳的.每个都有后果,因为它们影响导入路径以及其他人如何重用它们.

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

myproj/
  main/
    mypack.go
  mypack.go
Run Code Online (Sandbox Code Playgroud)

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

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

myproj/
  main/
    mypack.go
  myextras/
    someextra.go
  mypack.go
  mysupport.go
Run Code Online (Sandbox Code Playgroud)

要么

myproj.org/
  lib/
    mysupport.go
    myextras/
      someextra.go
  main/
    mypack.go
  mypage.go
Run Code Online (Sandbox Code Playgroud)

仅将文件放在lib目录中(如果它们不打算由另一个项目导入).换句话说,如果它们是私有支持文件.这就是lib将公共与私有接口分开的想法.

以这种方式做事将为您提供一个很好的导入路径,myproj.org/mypack以便在其他项目中重用代码.如果你使用lib那么内部支持文件将有一个指示的导入路径,myproj.org/lib/mysupport.

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

  • Idomatic是为主包使用`cmd/nameOfMyExecutable`子目录(如果你有多个命令,只需要`cmd/...`;参见`golang.org/x/tools/cmd`;否则交换它是很常见的在顶层有'main.go`).你的方式`go install`将创建一个"main"(或"main.exe")可执行文件.此外,惯用的是使用一个`internal`子目录作为包/程序内部的子包,并不打算在别处使用(预计Go的未来版本将强制执行没有其他人导入`internal`包完成这条路). (14认同)

eda*_*dap 21

我觉得非常有用了解如何在Golang这个章节组织代码http://www.golang-book.com/11由Caleb Doxsey编写的书


ale*_*otc 12

似乎没有组织Go项目的标准方法,但https://golang.org/doc/code.html指定了大多数项目的最佳实践.jdi的答案很好但是如果你使用github或bitbucket并且你还有其他库,你应该创建以下结构:

~/projects/
bin/
pkg/
src/
  github.com/
    username/
        mypack/
            foo.go
            bar.go
            mypack_test.go
        mylib/
            utillib.go
            utillib_test.go
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以为mylib创建一个单独的存储库,可以用于其他项目,并可以通过"go get"进行检索.您的mypack项目可以使用"github.com/username/mylib"导入您的库.欲获得更多信息:

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


noe*_*han 6

让我们探究该go get repository_remote_url命令如何在下管理项目结构$GOPATH。如果执行此操作go get github.com/gohugoio/hugo,它将在以下位置克隆存储库

$ GOPATH / src / repository_remote / user_name / project_name


$ GOPATH / src / github.com/gohugoio/hugo

这是创建初始项目路径的好方法。现在,让我们探索那里的项目类型是什么以及它们的内部结构如何组织。社区中的所有golang项目都可以归类为

  • Libraries (无可执行二进制文件)
  • Single Project (仅包含1个可执行二进制文件)
  • Tooling Projects (包含多个可执行二进制文件)

通常,golang项目文件可以根据任何设计原则(例如DDDPOD)打包

大多数可用的go项目都遵循此面向包设计

面向包的设计鼓励开发人员仅将实现保留在自己的包中,而不是/internal那些包之间无法通信的包


图书馆

  • 数据库驱动程序qt之类的项目可以归为此类。
  • 现在,某些库(例如color)遵循平面结构,没有任何其他软件包。
  • 这些库项目大多数都管理一个称为internal的软件包。
  • /internal 包主要用于对其他项目隐藏实现。
  • 没有任何可执行的二进制文件,因此没有包含main func的文件。

 ~/$GOPATH/
    bin/
    pkg/
    src/
      repository_remote/
        user_name/
            project_name/
              internal/
              other_pkg/
Run Code Online (Sandbox Code Playgroud)

单一专案

  • 诸如hugoetcd之类的项目在root级别和具有单个主要功能。
  • 目标是生成一个单一的二进制文件

工具项目

  • 项目如kubernetes去-复仇具有了一个叫做下组织主FUNC CMD
  • cmd/ 软件包管理我们要构建的二进制文件(工具)的数量

 ~/$GOPATH/
    bin/
    pkg/
    src/
      repository_remote/
        user_name/
            project_name/
              cmd/
                binary_one/
                   main.go
                binary_two/
                   main.go
                binary_three/
                   main.go
              other_pkg/
Run Code Online (Sandbox Code Playgroud)


Gus*_*tav 5

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

myproj/
   your-program/
      main.go
      lib.go
Run Code Online (Sandbox Code Playgroud)

然后运行:

~/myproj/your-program$ go build && ./your-program
Run Code Online (Sandbox Code Playgroud)