У меня есть проект, который становится все более сложным, и я хочу расположить файловую систему таким образом, чтобы уменьшить боль.
Есть ли какие-нибудь хорошие примеры того, что имеет смысл?
Обновление от мая 2013 г .: официальная документация находится в разделе « Организация кода »
Код Go должен храниться внутри рабочего пространства .
Рабочее пространство - это иерархия каталогов с тремя каталогами в корне:
src
содержит исходные файлы Go, организованные в пакеты (по одному пакету на каталог),pkg
содержит объекты пакета иbin
содержит исполняемые команды.
go tool
Строит исходные пакеты и устанавливают результирующие бинарники кpkg
иbin
каталогам.
src
Подкаталога обычно содержит несколько хранилищ контроля версий (например, для Git или ртутный) , которые отслеживают развитие одного или нескольких исходных пакетов.
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 г .: см. « Структурирование приложений в Go » от Бена Джонсона.
В этой статье есть такие советы:
объединение
main.go
файла и логики моего приложения в одном пакете имеет два последствия:
- Это делает мое приложение непригодным для использования в качестве библиотеки.
- У меня может быть только один двоичный файл приложения.
Я нашел лучший способ исправить это - просто использовать
cmd
каталог « » в моем проекте, где каждый из его подкаталогов представляет собой двоичный файл приложения.
camlistore/
cmd/
camget/
main.go
cammount/
main.go
camput/
main.go
camtool/
main.go
Перемещение
main.go
файла из корня позволяет создавать приложение с точки зрения библиотеки. Бинарный файл вашего приложения - это просто клиент библиотеки вашего приложения.Иногда вы можете захотеть, чтобы пользователи взаимодействовали несколькими способами, поэтому вы создаете несколько двоичных файлов.
Например, если у вас естьadder
пакет « », который позволяет пользователям складывать числа вместе, вы можете выпустить версию для командной строки, а также веб-версию.
Вы можете легко сделать это, организовав свой проект следующим образом:
adder/
adder.go
cmd/
adder/
main.go
adder-server/
main.go
Пользователи могут установить двоичные файлы вашего «сумматора» с помощью команды «go get» с многоточием:
$ go get github.com/benbjohnson/adder/...
И вуаля, у вашего пользователя установлены «
adder
» и «adder-server
»!
Обычно типы моих проектов очень связаны, поэтому он лучше подходит с точки зрения удобства использования и API.
Эти типы также могут использовать неэкспортированный вызов между ними, что делает API маленьким и понятным.
- Сгруппируйте связанные типы и код в каждом файле. Если ваши типы и функции хорошо организованы, я считаю, что файлы имеют размер от 200 до 500 SLOC. Может показаться, что это много, но мне легко ориентироваться. 1000 SLOC - это обычно мой верхний предел для одного файла.
- Организуйте наиболее важный тип в верхней части файла и добавьте типы по убыванию важности в нижней части файла.
- Как только ваше приложение начинает получать более 10 000 SLOC, вы должны серьезно оценить, можно ли его разбить на более мелкие проекты.
Примечание: последняя практика не всегда хороша:
Извините, я просто не могу согласиться с этой практикой.
Разделение типов на файлы помогает управлять кодом, удобочитаемостью, удобством обслуживания и тестирования.
Это также может гарантировать единую ответственность и соблюдение принципа открытого / закрытого ...
Правило, запрещающее циклическую зависимость, состоит в том, чтобы заставить нас иметь четкую структуру пакетов.
(Альтернатива от февраля 2013 г., src
только относительно )
Вы можете найти классический макет, проиллюстрированный в « Макете кода GitHub »:
Приложение и обе библиотеки находятся на 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.
Это вызвало некоторую критику на этой странице Reddit :
Я настоятельно рекомендую не структурировать репо так, как вы это делаете, это сломает "
go get
", что является одной из самых полезных вещей в Go.
Гораздо лучше писать код для людей, которые действительно знают Go, поскольку они, скорее всего, будут его компилировать.
А люди, которые этого не делают, по крайней мере, почувствуют язык.Поместите основной пакет в корень репо.
Разместите активы в подкаталоге (чтобы все было в порядке).
Храните основную часть кода в подпакете (на случай, если кто-то захочет повторно использовать его вне вашего двоичного файла).
Включите сценарий установки в корень репозитория, чтобы его было легко найти.Это всего лишь двухэтапный процесс для загрузки, сборки, установки и настройки:
- "
go get <your repo path>
": загружает и устанавливает код перехода с подкаталогом для ресурсов.$GOPATH/<your repo path>/setup.sh
: распределяет активы в нужное место и устанавливает службу
setup.sh
заключается в том, что Go достаточно кроссплатформенный, тогда как сценарии оболочки POSIX - нет.Я предполагаю, что под словом «проект» вы подразумеваете не пакет Go, а программное обеспечение, которое вы разрабатываете. В противном случае вы можете получить помощь здесь и здесь . Однако это не сильно отличается от написания пакетов для Go: используйте пакеты, создайте папку для каждого пакета и объедините эти пакеты в своем приложении.
Чтобы составить собственное мнение, вы можете посмотреть популярные репозитории Go на github: https://github.com/trending/go . Яркие примеры - Кэли и Зевс .
Самая популярная схема, вероятно, состоит в том, чтобы иметь основной файл Go и множество модулей и подмодулей в их собственных каталогах. Если у вас много метафайлов (документы, лицензии, шаблоны и т. Д.), Вы можете поместить исходный код в подкаталог. Вот что я делал до сих пор.
источник
$GOPATH/src
или используя ихgo get
-столы имен.doozerd
не очень хороший пример, даже его тесты слабые.Есть рекомендуемый подход от авторов Golang, который определяет, как разметить ваш код, чтобы он лучше всего работал с инструментами go и поддерживал системы контроля версий.
источник
$GOROOT
, а не код вsrc/<project>
каталоге.Вам, вероятно, также стоит взглянуть на это репо. Он показывает множество идей, как структурировать приложения Go: https://github.com/golang-standards/project-layout
источник