「GoCN酷Go推荐」env 环境变量获取库
背景
对于编译成二进制文件的程序而言,其本身就是一个黑盒子。程序的外部控制主要由三个部分组成:命令行参数,配置文件和环境变量。之前的文章中,我们已经拥有命令行参数工具库cobra,配置文件读取库viper,今天我们来了解一下在环境变量读取库中的一员env。
安装
go get github.com/caarlos0/env/v6
使用案例
package main
import (
"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:环境变量的获取名。
- unset:与env逗号隔开,表明环境变量值获取之后即刻清理,通常用于私密数据。
- file:将对应文件内容读取赋值。
- required: 毕竟从环境变量中读取到。
- notEmpty: 非空
- 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语言陷阱系列的视频来啦~戳下文即可观看~👇🏻👇🏻👇🏻
评论