Пакеты в Go — основной строительный блок для организации кода и управления областями видимости. Исторически Go избрал простую модель импортов и иерархии папок, чтобы сделать программирование прозрачным и избегать неопределённостей с разрешением зависимостей, как это было в C/C++ и Java. Проблема, которую Go решает, — это создание понятной структуры проекта, предотвращение конфликтов имён и независимость модулей друг от друга.
Проблема: Без единого подхода к организации невозможно масштабировать приложение, появляется дублирование, конфликты имён, циклические зависимости. Важно явно следить за областью видимости объектов.
Решение: Каждый каталог содержит файл с пакетом (package somepackage), имя каталога и имя пакета совпадают по best practice. Импорт осуществляется через ключевое слово import, а экспортируемыми становятся только объекты с большой буквы. Управление зависимостями — через go modules (go.mod).
Пример структуры и импорта:
// internal/mathops/add.go package mathops func Add(a, b int) int { return a + b } // main.go package main import ( "fmt" "myservice/internal/mathops" ) func main() { fmt.Println(mathops.Add(2, 3)) }
Ключевые особенности:
Можно ли в одном каталоге объявить несколько разных пакетов?
Нет, все файлы в каталоге должны принадлежать одному пакету.
Станут ли функции экспортируемыми, если у них название с большой буквы, а пакет назван с маленькой?
Да, экспорт зависит только от первой буквы имени объекта (функции, типа, переменной), а не от имени пакета.
Можно ли импортировать пакет с различным алиасом, и будет ли это влиять на видимость функций?
Да, можно. Алиас влияет только на то, каким именем обращаются к пакету, но не меняет область видимости:
import mymath "myservice/internal/mathops" mymath.Add(1,2)
Разработчик складывает все функции в один файл "utils.go" в пакете main, не выделяя бизнес-логику по отдельным пакетам.
Плюсы:
Минусы:
Бизнес-логика, утилиты, обработчики, модели данных вынесены в независимые пакеты: mathops, user, storage, api. Импорт строго по назначению, каждый пакет тестируем отдельно.
Плюсы:
Минусы: