Уроки модуля (5/5)
Создание ограничений и тегов
Ограничения сборки (также называемые тегами сборки) ограничивают компиляцию файла на основе ОС, архитектуры, версии Go или пользовательских тегов, передаваемых в командной строке. Они используются для кроссплатформенного кода, дополнительных тяжелых тестовых файлов и подобных сценариев.
Современный синтаксис: //go:build.
Начиная с Go 1.17+, каноническим форматом является специальный комментарий //go:build, размещаемый в верхней части файла перед package, на отдельной строке, за которой следует пустая строка:
//go:build linux
package main
// this file is built ONLY on LinuxТри абсолютных правила:
- Комментарий должен появиться перед
package. - За ним должна следовать пустая строка.
- Между
//иgo:buildнет пробела (это синтаксический триггер, а не просто комментарий).
Логические выражения
Выражение после //go:build допускает логические операторы:
//go:build linux && amd64 // both conditions
//go:build linux || darwin // any one (Unix-like)
//go:build !windows // negation
//go:build (linux || darwin) && !arm64
//go:build go1.22 // Go version ≥ 1.22
//go:build integration // custom tag (see below)Наиболее распространенные встроенные теги:
- ОС:
linux,darwin,windows,freebsd,js... - Архитектура:
amd64,arm64,386,wasm... - Версия Go:
go1.20,go1.22... (истина, если версия ≥). cgo: true, если cgo включен.
Кроссплатформенность: соглашение об именах файлов
Помимо явных тегов, Go распознает суффиксы имен файлов как неявные ограничения сборки:
db_linux.go // linux only
db_windows.go // windows only
db_linux_amd64.go // linux/amd64 only
Это идиоматический шаблон для платформозависимых реализаций одного и того же интерфейса (каждый файл определяет одни и те же функции с разным кодом).
Пользовательские теги: выбор в пользу тяжелых тестов
Пользовательские теги – это любой идентификатор, который вы передаёте в командной строке:
//go:build integration
package mypkg
// tests that need a real DB, run only on demandИсполнение:
go test -tags=integration ./...Без -tags=integration файл невидим для компилятора (тесты внутри него не существуют для go test). Это канонический способ отделить модульные тесты (всегда) от интеграционных тестов (по требованию, возможно, только в CI).
Старый синтаксис: // +build (устаревший)
До версии 1.17 формат был // +build linux (обратите внимание на пробел и на то, что это +build, а не go:build). Он по-прежнему поддерживается для обратной совместимости, но gofmt в Go 1.17+ добавляет оба, когда находит только старый:
//go:build linux
// +build linux
package mainДля новых файлов используйте только современную форму //go:build.
Упражнения
Вверху файла добавьте ограничение сборки, которое компилирует его ТОЛЬКО в Linux. Помните пустую строку перед пакетом.
Показать подсказку
Комментарий //go:build идет ПЕРЕД пакетом на отдельной строке, за которой следует пустая строка.
Решение доступно после 3 попыток
Добавьте ограничение сборки, ИСКЛЮЧАЮЩЕЕ Windows (используйте оператор отрицания!).
Решение доступно после 3 попыток
Какой флаг вы используете, чтобы включить во время тестирования специальный тег интеграции, объявленный с помощью интеграции //go:build?
$ go test -tags=???