У мене є проект, який починає ускладнюватися, і хочу розкласти файлову систему таким чином, щоб зменшити біль.
Чи є якісь хороші приклади, що має сенс?
У мене є проект, який починає ускладнюватися, і хочу розкласти файлову систему таким чином, щоб зменшити біль.
Чи є якісь хороші приклади, що має сенс?
Відповіді:
Оновлення травня 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 року: див. " Структурування додатків у роботі " від Бен Джонсон
Ця стаття містить поради, як-от:
поєднання
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
Користувачі можуть встановити ваші бінарні додатки "adder" із "go get" за допомогою еліпсису:
$ go get github.com/benbjohnson/adder/...
І вуаля, у вашого користувача встановлені "
adder
" і "adder-server
"!
Зазвичай типи мого проекту дуже пов'язані, тому він краще підходить з точки зору зручності використання та API.
Ці типи також можуть скористатися викликом неекспортованого між ними, що забезпечує API невеликим і зрозумілим.
- Згрупуйте типи та код, пов’язаний із кожним файлом разом. Якщо ваші типи та функції добре організовані, я вважаю, що файли мають значення від 200 до 500 SLOC. Це може здатись дуже багато, але мені легко переходити. 1000 SLOC зазвичай є моєю верхньою межею для одного файлу.
- Упорядкуйте найважливіший тип у верхній частині файлу та додайте типи із зменшенням значення у нижній частині файлу.
- Як тільки ваша заявка починає перевищувати 10000 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 checkout.
Хоча це викликало критику на цій сторінці для редагування :
Я настійно рекомендую не структурувати репо, як у вас є, він порушиться "
go get
", що є однією з найкорисніших речей про Go.
Набагато краще написати свій код для людей, які знають, що йдуть Go, оскільки вони, швидше за все, саме ті, хто їх компілює.
А для людей, які цього не роблять, вони принаймні відчують мову.Покладіть основний пакет в корінь репо.
Майте активи в підкаталозі (щоб все було чітко).
Зберігайте м'ясо коду в підпаку (якщо хтось хоче повторно використовувати його поза вашим бінарним файлом).
Включіть сценарій налаштування в корінь репо, щоб його легко знайти.Це ще лише процес, який завантажують, встановлюють та встановлюють у два кроки:
- "
go get <your repo path>
": завантажує та встановлює код go, з підкаталогом для активів$GOPATH/<your repo path>/setup.sh
: розподіляє активи в потрібне місце і встановлює сервіс
Я припускаю, що під проектом ви маєте на увазі не пакет програм Go, а програмне забезпечення, яке ви розробляєте. Інакше можна отримати допомогу тут і тут . Однак це не так сильно відрізняється від написання пакетів для Go: Використовуйте пакети, створюйте папки для кожного пакету та комбінуйте ці пакунки у вашій програмі.
Щоб скласти собі думку, ви можете переглянути тенденційні сховища Go на github: https://github.com/trending/go . Характерними прикладами є Кейлі і Zeus .
Найпопулярніша схема, мабуть, має головний файл Go та багато модулів та підмодулів у власних каталогах. Якщо у вас багато метафайлів (doc, ліцензія, шаблони, ...), можливо, ви захочете ввести вихідний код у підкаталог. Ось що я робив досі.
$GOPATH/src
або з використанням їх go get
-табельних імен.
doozerd
це не гарний приклад, навіть його тести слабкі.
Авторами Golang є рекомендований підхід, який визначає, як компонувати код, щоб найкраще працювати з інструментами go і підтримувати системи управління джерелами
$GOROOT
, а не код всередині src/<project>
каталогу.
Ви, мабуть, також повинні заглянути в це репо. Тут показано багато ідей, як структурувати додатки: https://github.com/golang-standards/project-layout
setup.sh
полягає в тому, що Go є досить кросплатформенним, тоді як сценарії оболонки POSIX - ні.