16 вопросов
Пакет - единица компиляции и пространства имён. Один каталог - один пакет (один package в файлах каталога). Импорт по модульному пути: import "example.com/mypkg". Публичные идентификаторы - с заглавной буквы. Функция main в пакете main - точка входа.
Создать каталог, в нём .go файлы с package mypkg. В модуле путь импорта - по go.mod: module example.com/repo, тогда подпакет example.com/repo/mypkg. Импорт: import "example.com/repo/mypkg"; использование: mypkg.Func() или алиас import m "example.com/repo/mypkg".
Файл в корне модуля: объявляет модуль (module path) и версии зависимостей (require, replace, exclude). Команды go build, go test читают go.mod и при необходимости обновляют зависимости. Минимальная версия Go задаётся директивой go 1.21. go mod init, go mod tidy, go get управляют модулем.
Хеши (checksums) загруженных модулей и их зависимостей. Гарантирует воспроизводимость сборки: те же версии дают те же хеши. Добавляется/обновляется при go get, go mod tidy. В репозиторий коммитят и go.mod, и go.sum.
Приводит go.mod и go.sum в соответствие с исходным кодом: добавляет недостающие зависимости, удаляет неиспользуемые, обновляет go.sum. Запускают после изменения импортов или перед коммитом. Полезно для чистоты зависимостей.
Пакеты в каталоге internal/ видны только модулю, содержащему этот каталог (и его подмодулям). Импорт из другого модуля запрещён. Используется для приватной части проекта, не для публичного API.
Типичная структура: cmd/ содержит подкаталоги с приложениями (точками входа). Например, cmd/server/main.go, cmd/cli/main.go. Каждый подкаталог - пакет main, отдельный бинарник. Удобно для проектов с несколькими исполняемыми файлами.
Встроенные идентификаторы языка: типы (int, string, error, bool и т.д.), константы (true, false, iota, nil), функции (len, cap, make, new, append, copy, close, panic, recover и др.). Импортировать builtin не нужно - они всегда в области видимости.
Каталог vendor/ в корне модуля хранит копии зависимостей. При сборке Go использует их вместо загрузки из сети. go mod vendor создаёт/обновляет vendor. Нужен для офлайн-сборки или фиксации точных версий без внешнего прокси.
go build собирает пакет в текущей директории или указанный, бинарник в текущем каталоге (или -o). go install собирает и устанавливает бинарник в $GOPATH/bin (или $GOBIN). Обычно для установки утилит: go install example.com/cmd/tool@latest.
Статический анализ кода: подозрительные конструкции, частые ошибки (например, неправильная сигнатура Printf, потеря контекста err, копирование мьютекса, неиспользуемые результаты). Запуск: go vet ./.... Часто включают в CI. Часть проверок - в golang.org/x/tools.
В go.mod: require example.com/pkg v1.2.3. Версия - семантическая (vMAJOR.MINOR.PATCH). go get обновляет версии; @latest, @v1.2.3, @master. Непрямые зависимости добавляются с // indirect. Минимальная версия: при сборке выбирается минимальная подходящая версия среди требований.
Корень с go.mod; cmd/ - приложения; internal/ - приватный код; pkg/ или корень - публичные пакеты; api/, web/ - по необходимости. Тесты рядом с кодом (_test.go). Документация - README, doc в коде. Не жёсткий стандарт, но распространённый подход.
replace example.com/pkg => ./local/pkg или => other.com/pkg v1.0.0. Подменяет зависимость локальным путём или другим модулем. Используется для локальной разработки, форков, обхода проблем. В продакшн-коде осторожно - обычно для временных решений.
Режим workspace: файл go.work перечисляет несколько модулей для совместной разработки. Команды go видят их как один набор модулей; изменения в одном модуле сразу видны в другом без публикации. go work init, go work use ./module. Удобно для монорепо и локальных зависимостей.
import _ "pkg" - blank (анонимный) импорт: пакет загружается только ради side-effect (обычно init()). Используется для регистрации драйверов (например, import _ "github.com/lib/pq"), плагинов. import . "pkg" - импорт в текущее пространство имён (редко, мешает читаемости).