背景
对于编译成二进制文件的程序而言,其本身就是一个黑盒子。程序的外部控制主要由三个部分组成:命令行参数,配置文件和环境变量。之前的文章中,我们已经拥有命令行参数工具库cobra,配置文件读取库viper,今天我们来了解一下在环境变量读取库中的一员env。
安装
go get github.com/caarlos0/env/v6
使用案例
package mainimport ("fmt""time""github.com/caarlos0/env/v6"
)type config struct {Home string `env:"HOME"`Port int `env:"PORT" envDefault:"3000"`Password string `env:"PASSWORD,unset"`IsProduction bool `env:"PRODUCTION"`Hosts []string `env:"HOSTS" envSeparator:":"`Duration time.Duration `env:"DURATION"`TempFolder string `env:"TEMP_FOLDER" envDefault:"${HOME}/tmp" envExpand:"true"`
}func main() {cfg := config{}if err := env.Parse(&cfg); err != nil {fmt.Printf("%+v\n", err)}fmt.Printf("%+v\n", cfg)
}
接下来我们针对代码中涉及的tag逐一进行分析:
env:环境变量的获取名。
envDefault:顾名思义,当获取不到环境变量值时的默认值。
envSeparator: 当变量是字符串数组时,此值对应切分时使用的字符。
envExpand:通常与envDefault配合使用,允许使用环境变量对envDefault的值格式化。
扩展
env库的公开函数中,使用ParseWithFuncs可以传入自定义的类型解析函数,其类型为map[reflect.Type]func(v string) (interface{}, error)。如此通过形如type Myint int的方式,让解析过程能拥有更大的灵活性。
源码悄悄看
env库的主要功能源码不过500行,其中使用了大量reflect库的反射机制,用于对环境变量值到结构体成员类型的转换,defaultBuiltInParsers定义了其默认的类型解析函数。解析流程:
通过os.Environ()获得环境变量字符串key=value形式,转换成map[string]string结构。
通过反射循环获取结构体变量信息,包括变量类型和对应tag
使用设定对应的解析函数,其中若是结构体则递归调用
根据tag指定的逻辑对解析后的值进行判断和处理
对结构体变量赋值
总结
环境变量在程序中的使用随着微服务项目的普及而越来越常见。环境变量可以看作是操作系统层面的配置文件,因此我们通常会把与业务相关的参数写在配置文件中,会把与程序系统功能相关的参数配置在环境变量中。
相关链接
https://github.com/caarlos0/env
《酷Go推荐》招募:
各位Gopher同学,最近我们社区打算推出一个类似GoCN每日新闻的新栏目《酷Go推荐》,主要是每周推荐一个库或者好的项目,然后写一点这个库使用方法或者优点之类的,这样可以真正的帮助到大家能够学习到
新的库,并且知道怎么用。
大概规则和每日新闻类似,如果报名人多的话每个人一个月轮到一次,欢迎大家报名!戳「阅读原文」,即可报名
扫码也可以加入 GoCN 的大家族哟~
Go语言陷阱系列的视频来啦~戳下文即可观看~👇🏻👇🏻👇🏻