Организация проекта с несколькими файлами 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/