Go 的 Compile-Time Variable Injection
背景
本次在进行公司项目工作时,我尝试寻找一种无需 .env 即可在 컴파일 타임 时注入 변수 的方法。我认为这样做会非常 편리,因为无需 .env
或多个 콘피그 文件,只需单个文件即可。
起初我尝试寻找基于 .env
生成 상수 文件的 go:generate
CLI 之类的工具,但没有找到。
然而,如果那样的话,直接修改 constants 即可,无需麻烦地进行 gen;我找到了一个类似于 러스트 中的 include_bytes!
매크로,可以在 컴파일 타임 时注入 값 的方法。
컴파일 타임 변수 주입
使用方法很简单。
1package main
2
3import "fmt"
4
5var Foo string
6
7func main() {
8 fmt.Println(Foo)
9}
假设有如上代码,在 빌드 时可以按如下方式注入:
1go build -ldflags="-X 'main.Foo=bar'"
通过 ldflag 传递 인자,在 빌드 时会在 컴파일 타임 将 bar
的 값 注入到 Foo
변수 中。很简单。
如果项目中在多个地方存在同名的 패키지 或 변수,则需要明确指定 패키지 路径。
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'"
即使在同一个 패키지 中存在多个 변수,也只需传递额外的 인자 即可。
1go build -ldflags="-X 'main.Version=v1.0.0' -X 'main.BuildTime=2025-05-27' -X 'main.GitCommit=abc123'"
特征如下:
- 변수 无需为 public: 小写字母开头的 변수 也可注入
- 仅支持 string 타입: 不支持其他 타입