Compile-Time Variable Injection в Go
Предыстория
Работая над проектом компании на этот раз, я искал способ внедрения переменных во время компиляции (compile time
) без использования .env
.
Я полагал, что это будет крайне удобно, поскольку потребуется всего один файл вместо .env
или множества файлов конфигурации.
Сначала я искал что-то вроде go:generate
CLI, который генерирует файлы констант на основе .env
, но такого инструмента не нашлось.
Однако, если бы такой инструмент существовал, было бы проще просто изменить constants
напрямую, а не утруждаться генерацией (gen
), поэтому я искал способ внедрения значений во время компиляции (compile time
), подобно макросу include_bytes!
в Rust.
Внедрение переменных во время компиляции (Compile Time Variable Injection
)
Использование простое.
1package main
2
3import "fmt"
4
5var Foo string
6
7func main() {
8 fmt.Println(Foo)
9}
Если предположить, что имеется код, подобный приведенному выше, его можно внедрить во время сборки (build
) следующим образом.
1go build -ldflags="-X 'main.Foo=bar'"
Если аргументы передаются через ldflag
, значение bar
внедряется в переменную Foo
во время компиляции (compile time
) в процессе сборки (build
). Это просто.
Если в проекте есть пакеты (package
) или переменные (variable
) с одинаковым именем в нескольких местах, можно указать путь к пакету (package path
).
1// github.com/myproject/config/config.go
2package config
3
4var Version string
5
6// github.com/myproject/internal/config/config.go
7package config
8
9var BuildTime string
В таких случаях их можно внедрить раздельно следующим образом:
1go build -ldflags="-X 'github.com/myproject/config.Version=v1.0.0' -X 'github.com/myproject/internal/config.BuildTime=2025-05-27'"
Даже если в одном пакете (package
) имеется несколько переменных (variable
), можно просто передать дополнительные аргументы.
1go build -ldflags="-X 'main.Version=v1.0.0' -X 'main.BuildTime=2025-05-27' -X 'main.GitCommit=abc123'"
Особенности следующие:
- Переменные (
variable
) не обязательно должны быть публичными (public
): Переменные, начинающиеся со строчной буквы, также могут быть внедрены. - Поддерживается только тип
string
: Другие типы не поддерживаются.