Go 编译时变量注入:go build -ldflags -X 用法详解
By wHoIsDReAmer views ...

背景
这次在公司项目工作中,我查找了是否有不使用 .env 而在编译时注入变量的方法。我想,这样只需要一个文件,而无需 .env 或多个配置文件,应该会非常方便。
最初我查找的是能够基于 .env 生成常量文件的 go:generate CLI 之类的工具,但没有找到。
不过,既然这样,直接修改 constants 就行了,没必要麻烦地再执行 gen,于是我找到了类似 Rust 中 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'"
其特点如下:
- 变量无需为公开的:以小写字母开头的变量也可以注入
- 仅支持 string 类型:不支持其他类型