「GoCN酷Go推荐」env 环境变量获取库

共 1767字,需浏览 4分钟

 ·

2021-11-30 17:13


背景

对于编译成二进制文件的程序而言,其本身就是一个黑盒子。程序的外部控制主要由三个部分组成:命令行参数,配置文件和环境变量。之前的文章中,我们已经拥有命令行参数工具库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语言陷阱系列的视频来啦~戳下文即可观看~👇🏻👇🏻👇🏻


浏览 30
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报