Организация проекта с несколькими файлами Go

Примечание: этот вопрос связан с этим, но два года - очень долгое время в истории Go.

Каков стандартный способ организации проекта Go во время разработки?

Мой проект представляет собой единый пакет mypack, поэтому, я думаю, я поместил все .go файлы в каталог mypack.

Но тогда я бы хотел протестировать его во время разработки, поэтому мне нужен хотя бы файл, объявляющий пакет main, так что я могу сделать go run trypack.go

Как мне организовать это? Мне нужно делать go install mypack каждый раз, когда я хочу попробовать?

Ответ 1

Я бы порекомендовал просмотреть эту страницу на Как написать код Go

Это документы как, как структурировать свой проект в go build дружественно, а также как писать тесты. Тесты не должны быть cmd с использованием main пакета. Они могут быть просто именованными функциями TestX как часть каждого пакета, и затем go test обнаружит их.

Структура, предложенная в этой ссылке в вашем вопросе, немного устарела, теперь с выпуском Go 1. Вам больше не нужно размещать каталог pkg в src. Единственные 3 директории, связанные со спецификацией - это 3 в корне вашей GOPATH: bin, pkg, src. Под src вы можете просто поместить свой проект mypack, а под ним - все ваши файлы .go, включая mypack_test.go

go build будет встроен в корневой уровень pkg и bin.

Так что ваша ГОПАТА может выглядеть так:

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

export GOPATH=$HOME/projects

$ go build mypack
$ go test mypack

Обновление: начиная с> = Go 1.11, система Module теперь является стандартной частью инструментария, и концепция GOPATH близка к устареванию.

Ответ 2

jdi имеет правильную информацию об использовании GOPATH. Я бы добавил, что если вы намереваетесь иметь двоичный файл, вы можете добавить еще один уровень в каталоги.

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

running go build myproj/mypack построит пакет mypack вместе с его зависимостями running go build myproj/myapp построит двоичный файл myapp вместе с его зависимостями, которые, вероятно, содержат библиотеку mypack.

Ответ 3

Я изучил ряд проектов Go, и есть небольшая вариация. Вы можете рассказать, кто приходит с C и кто приходит с Java, как прежний дамп всего около всего в корневом каталоге проектов в пакете main, и последние, как правило, помещают все в каталог src. Однако оптимальным не является. Каждый из них имеет последствия, поскольку они влияют на пути импорта и другие способы их повторного использования.

Чтобы получить наилучшие результаты, я разработал следующий подход.

myproj/
  main/
    mypack.go
  mypack.go

Где mypack.go есть package mypack и main/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, не создавая отдельные проекты. например main/myfoo/myfoo.go и main/mybar/mybar.go.

Ответ 4

Мне очень полезно понять, как организовать код в Голанге в этой главе http://www.golang-book.com/11 книги, написанной Калебом Докси.

Ответ 5

Кажется, что нет стандартного способа организации проектов 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

Таким образом, у вас может быть отдельный репозиторий для mylib, который может быть использован для других проектов и может быть получен с помощью "go get". Проект mypack может импортировать вашу библиотеку, используя "github.com/username/mylib". Для получения дополнительной информации:

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

Ответ 6

Храните файлы в одном каталоге и используйте package main во всех файлах.

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

Затем запустите:

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

Ответ 7

Позвольте проводнику узнать, как команда go get repository_remote_url управляет структурой проекта в $GOPATH. Если мы go get github.com/gohugoio/hugo он будет клонировать репозиторий под

$ GOPATH/src/repository_remote/имя_пользователя/имя_проекта


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

Это хороший способ создать начальный путь проекта. Теперь давайте исследуем, какие типы проектов существуют и как организованы их внутренние структуры. Все проекты Голанга в сообществе можно отнести к категории

  • Libraries (без исполняемых двоичных файлов)
  • Single Project (содержит только 1 исполняемый файл)
  • Tooling Projects (содержит несколько исполняемых файлов)

Обычно файлы проекта golang могут быть упакованы в соответствии с любыми принципами проектирования, такими как DDD, POD

Большинство доступных проектов Go следуют этому пакетно-ориентированному дизайну

Пакетно-ориентированный дизайн поощряет разработчика сохранять реализацию только внутри своих собственных пакетов, за исключением пакета /internal который эти пакеты не могут связать друг с другом.


Библиотеки

  • Такие проекты, как драйверы баз данных, qt можно поставить под эту категорию.
  • Некоторые библиотеки, такие как color, теперь следуют плоской структуре без каких-либо других пакетов.
  • Большинство этих библиотечных проектов управляет пакетом, называемым внутренним.
  • /internal пакет в основном используется, чтобы скрыть реализацию от других проектов.
  • У вас нет исполняемых двоичных файлов, поэтому нет файлов, содержащих основную функцию.

 ~/$GOPATH/
    bin/
    pkg/
    src/
      repository_remote/
        user_name/
            project_name/
              internal/
              other_pkg/

Единый Проект

  • Такие проекты, как hugo и т.д., Имеют единственную основную функцию на корневом уровне и.
  • Цель состоит в том, чтобы создать один единственный двоичный файл

Инструментальные проекты

  • Такие проекты, как kubernetes, go-ethereum имеют несколько основных функций, организованных в виде пакета под названием cmd
  • cmd/ package управляет количеством двоичных файлов (инструментов), которые мы хотим построить

 ~/$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/