Структура проєкту та робочі простори¶
Go має тверду думку щодо кількох каталогових домовленостей і навмисно мовчить про решту. Ця стаття розглядає патерни структури, які інструменти насправді розуміють, і робочі простори (workspaces) для розробки кількох модулів одночасно.
Домовленості, які інструменти забезпечують¶
Дві назви каталогів мають реальне значення для команди go:
internal/— пакети під каталогомinternal/можна імпортувати лише з коду, укоріненого в батьківському каталозіinternal/. Це забезпечена компілятором приватність на рівні дерева пакетів.testdata/— ігнорується інструментами збірки; місце для тестових фікстур.
example.com/shop/
├── go.mod
├── internal/
│ └── auth/ # імпортується лише в межах example.com/shop/...
└── store/
└── testdata/ # фікстури, ігноруються компілятором
Усе інше щодо структури — це домовленість, а не правило.
Правило internal/ забезпечує компілятор — імпорт ззовні батьківського
піддерева не вдасться:
// з іншого модуля, що імпортує example.com/shop/internal/auth
import _ "example.com/shop/internal/auth"
// compile error: use of internal package example.com/shop/internal/auth not allowed
cmd/ та поширена структура¶
Широко вживана (але необов'язкова) форма відокремлює точки входу від коду бібліотек:
cmd/<name>/— один каталог на кожну виконувану програму, кожен зі своїмpackage main. Назва каталогу стає назвою бінарника.internal/— приватні пакети, основна маса коду.- пакети верхнього рівня — публічний API модуля, якщо його призначено для імпорту.
myapp/
├── go.mod
├── cmd/
│ ├── server/main.go # збирає бінарник "server"
│ └── cli/main.go # збирає бінарник "cli"
├── internal/
│ ├── store/
│ └── auth/
└── api/ # експортований, доступний для імпорту іншим
Зберіть конкретну команду за її шляхом:
З погляду Python: немає вимоги
src/і немає__init__.py. Каталог є пакетом завдяки своїм файлам.go;cmd/таinternal/— це приблизні відповідники теки скриптів/точок входу та приватного підпакета.
Тримайте main тонким¶
Сильна домовленість: package main має робити якомога менше — розбирати
прапорці, з'єднувати все докупи, викликати пакети з internal/ — щоб
справжня логіка лишалася придатною до тестування та імпорту. Бінарник — це
клей; пакети — це програма.
Робочі простори: розробка кількох модулів разом¶
Коли ви змінюєте два модулі одночасно — скажімо, застосунок і бібліотеку,
від якої він залежить, — редагування go.mod із replace для кожного
працює, але це марудно й легко закомітити випадково. Робочий простір
вирішує це файлом go.work, який наказує команді go використовувати
кілька локальних модулів разом.
Тепер збірка чи тестування з будь-якого місця в робочому просторі вирішує
імпорти ./lib у вашу локальну копію — без директив replace. Додавайте
ще через go work use ./other.
Ключова практика: go.work лише локальний. Він для циклу розробки
кількох модулів на вашій машині, тож його зазвичай ігнорують у git і
ніколи не публікують. Випущені збірки все одно вирішують залежності через
go.mod/go.sum.
Швидка довідка¶
| Шлях / файл | Значення |
|---|---|
internal/ |
імпортується лише в межах піддерева батьківського модуля |
testdata/ |
тестові фікстури, ігноруються збіркою |
cmd/<name>/ |
одна виконувана програма на підкаталог (package main) |
go build ./cmd/x |
зібрати конкретну команду |
go.work (go work init/use) |
використовувати кілька локальних модулів разом |
тонкий main |
логіка живе в пакетах, придатних до імпорту |