golang环境变量解析到结构体插件库env的使用
Golang环境变量解析到结构体插件库env的使用
介绍
env是一个简单、零依赖的库,用于将环境变量解析到结构体中。
安装
go get github.com/caarlos0/env/v11
快速开始
基本用法
type config struct {
Home string `env:"HOME"`
}
// 解析方式1
var cfg config
err := env.Parse(&cfg)
// 解析方式2(使用泛型)
cfg, err := env.ParseAs[config]()
完整示例
package main
import (
"fmt"
"time"
"github.com/caarlos0/env/v11"
)
// 配置结构体
type Config struct {
Home string `env:"HOME"` // 基本字符串类型
Port int `env:"PORT" envDefault:"3000"` // 带默认值的整型
IsProduction bool `env:"PRODUCTION"` // 布尔类型
Hosts []string `env:"HOSTS" envSeparator:":"` // 字符串切片,使用:分隔
Duration time.Duration `env:"DURATION"` // 时间间隔类型
TempFolder string `env:"TEMP_FOLDER,expand"` // 支持变量扩展
RequiredVar string `env:"REQUIRED_VAR,required"` // 必填字段
SecretFile string `env:"SECRET_FILE,file"` // 从文件读取内容
}
func main() {
// 设置环境变量(实际使用时从系统环境变量获取)
os.Setenv("HOME", "/tmp/home")
os.Setenv("HOSTS", "host1:host2:host3")
os.Setenv("DURATION", "1h30m")
os.Setenv("TEMP_FOLDER", "$HOME/tmp") // 使用变量扩展
os.Setenv("REQUIRED_VAR", "must have")
os.Setenv("SECRET_FILE", "./secret.txt")
// 解析环境变量到结构体
var cfg Config
if err := env.Parse(&cfg); err != nil {
fmt.Printf("Failed to parse env: %v\n", err)
return
}
// 输出解析结果
fmt.Printf("Home: %s\n", cfg.Home)
fmt.Printf("Port: %d\n", cfg.Port)
fmt.Printf("IsProduction: %t\n", cfg.IsProduction)
fmt.Printf("Hosts: %v\n", cfg.Hosts)
fmt.Printf("Duration: %v\n", cfg.Duration)
fmt.Printf("TempFolder: %s\n", cfg.TempFolder)
fmt.Printf("RequiredVar: %s\n", cfg.RequiredVar)
fmt.Printf("SecretFile: %s\n", cfg.SecretFile)
}
主要功能
Parse
: 将当前环境解析到指定类型ParseAs
: 使用泛型将当前环境解析到指定类型ParseWithOptions
: 使用自定义选项解析环境变量ParseAsWithOptions
: 使用自定义选项和泛型解析环境变量Must
: 可以包装Parse.*调用,在出错时panicGetFieldParams
: 获取类型的env解析选项GetFieldParamsWithOptions
: 使用自定义选项获取类型的env解析选项
支持的类型
env支持所有内置类型,以及一些常用类型:
- 基本类型:
bool
,string
, 各种整型和浮点型 - 时间类型:
time.Duration
,time.Location
- 其他:
encoding.TextUnmarshaler
,url.URL
- 指针、切片和指针切片
- 上述类型的映射(map)
标签说明
env
: 设置环境变量名,并可接受下面描述的标签选项envDefault
: 设置字段的默认值envPrefix
: 可用于复杂类型字段,为其所有环境变量设置前缀envSeparator
: 设置切片和映射中项的分隔符(默认:,
)envKeyValSeparator
: 设置映射中键和值的分隔符(默认::
)
注意事项
未导出的字段会被env忽略,这是设计如此且不会改变。
高级选项
env
标签支持以下选项:
,expand
: 扩展环境变量,例如FOO_${BAR}
,file
: 指示变量内容是应读取的文件路径,init
: 初始化nil指针,notEmpty
: 如果环境变量为空则报错,required
: 如果环境变量未设置则报错,unset
: 使用后取消设置环境变量
解析选项
对于以WithOptions
结尾的函数,有以下选项可用:
Environment
: 用于替代os.Environ()
的键值对TagName
: 指定要使用的标签名而不是默认的env
PrefixTagName
: 指定要使用的前缀标签名而不是默认的envPrefix
DefaultValueTagName
: 指定要使用的默认值标签名而不是默认的envDefault
RequiredIfNoDef
: 如果未声明envDefault
,则将所有env
字段设置为必需OnSet
: 允许挂钩到env解析并在设置值时执行某些操作Prefix
: 在所有环境变量中使用的前缀UseFieldNameByDefault
: 定义如果env
键缺失时是否默认使用字段名FuncMap
: 自定义类型的解析函数
更多关于golang环境变量解析到结构体插件库env的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang环境变量解析到结构体插件库env的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang 环境变量解析到结构体 - env 库使用指南
在 Go 开发中,将环境变量解析到结构体是一种常见的配置管理方式。env
是一个流行的 Go 库,可以方便地将环境变量映射到结构体字段。下面我将详细介绍如何使用这个库。
安装 env 库
首先需要安装 env
库:
go get github.com/caarlos0/env/v7
基本用法
1. 定义配置结构体
package main
import (
"fmt"
"time"
"github.com/caarlos0/env/v7"
)
type Config struct {
Home string `env:"HOME"`
Port int `env:"PORT" envDefault:"3000"`
Password string `env:"PASSWORD,required"`
IsProduction bool `env:"PRODUCTION"`
Hosts []string `env:"HOSTS" envSeparator:":"`
Duration time.Duration `env:"DURATION"`
TempFolder string `env:"TEMP_FOLDER" envDefault:"${HOME}/tmp"`
}
2. 解析环境变量到结构体
func main() {
cfg := Config{}
if err := env.Parse(&cfg); err != nil {
fmt.Printf("%+v\n", err)
}
fmt.Printf("%+v\n", cfg)
}
标签说明
env:"VAR_NAME"
- 指定环境变量名envDefault:"value"
- 设置默认值required
- 标记该字段为必填envSeparator:":"
- 指定切片类型的分隔符unset
- 解析后从环境中删除该变量
高级用法
1. 自定义解析器
type CustomType struct {
Value string
}
func (c *CustomType) UnmarshalText(text []byte) error {
c.Value = string(text) + "-custom"
return nil
}
type Config struct {
Custom CustomType `env:"CUSTOM"`
}
func main() {
os.Setenv("CUSTOM", "value")
cfg := Config{}
if err := env.Parse(&cfg); err != nil {
panic(err)
}
fmt.Println(cfg.Custom.Value) // 输出: value-custom
}
2. 嵌套结构体
type NestedConfig struct {
Foo string `env:"FOO"`
Bar int `env:"BAR"`
}
type Config struct {
Nested NestedConfig `envPrefix:"NESTED_"`
}
func main() {
os.Setenv("NESTED_FOO", "foo")
os.Setenv("NESTED_BAR", "42")
cfg := Config{}
if err := env.Parse(&cfg); err != nil {
panic(err)
}
fmt.Printf("%+v\n", cfg.Nested) // 输出: {Foo:foo Bar:42}
}
3. 环境变量扩展
type Config struct {
Home string `env:"HOME"`
ConfigPath string `env:"CONFIG_PATH" envDefault:"${HOME}/.config/app"`
}
func main() {
cfg := Config{}
if err := env.Parse(&cfg); err != nil {
panic(err)
}
fmt.Println(cfg.ConfigPath) // 输出类似: /home/user/.config/app
}
完整示例
package main
import (
"fmt"
"log"
"os"
"time"
"github.com/caarlos0/env/v7"
)
type Config struct {
AppName string `env:"APP_NAME" envDefault:"MyApp"`
Debug bool `env:"DEBUG"`
Port int `env:"PORT" envDefault:"8080"`
Timeout time.Duration `env:"TIMEOUT" envDefault:"30s"`
DatabaseURL string `env:"DATABASE_URL,required"`
AllowedHosts []string `env:"ALLOWED_HOSTS" envSeparator:","`
FeatureFlags struct {
NewUI bool `env:"FEATURE_NEW_UI"`
DarkMode bool `env:"FEATURE_DARK_MODE" envDefault:"true"`
} `envPrefix:"FEATURE_"`
}
func main() {
// 设置一些环境变量(实际使用时从系统环境变量获取)
os.Setenv("DATABASE_URL", "postgres://user:pass@localhost:5432/db")
os.Setenv("ALLOWED_HOSTS", "localhost,127.0.0.1,example.com")
os.Setenv("FEATURE_NEW_UI", "true")
var cfg Config
if err := env.Parse(&cfg); err != nil {
log.Fatalf("Failed to parse config: %v", err)
}
fmt.Printf("Config: %+v\n", cfg)
fmt.Printf("AppName: %s\n", cfg.AppName)
fmt.Printf("Port: %d\n", cfg.Port)
fmt.Printf("DatabaseURL: %s\n", cfg.DatabaseURL)
fmt.Printf("AllowedHosts: %v\n", cfg.AllowedHosts)
fmt.Printf("FeatureFlags - NewUI: %v, DarkMode: %v\n",
cfg.FeatureFlags.NewUI, cfg.FeatureFlags.DarkMode)
}
注意事项
- 结构体字段必须是可导出的(首字母大写)
- 对于必填字段(required),如果未设置会返回错误
- 默认值仅在环境变量未设置时使用
- 支持基本类型、切片、嵌套结构体和自定义类型
env 库提供了一种简洁、类型安全的方式来管理应用程序配置,特别适合12-factor应用开发。通过结构体标签,可以清晰地表达配置需求,使代码更易于维护和理解。
希望这个指南能帮助你有效地使用 env 库来管理 Go 应用程序的环境变量配置!