该包的实现是基于标准库os/env包中的相关函数(比如Getenv)来获取系统的环境变量的。获取到环境变量值后,再通过结构体中的tag,将值映射到对应的结构体字段上。
使用示例
下面是将系统的一些环境变量映射到config结构体的示例。如下:
我们可以像以下这样运行该代码:
代码语言:javascript复制$ PRODUCTION=true HOSTS="host1:host2:host3" DURATION=1s go run main.go
{Home:/your/home Port:3000 IsProduction:true Hosts:[host1 host2 host3] Duration:1s}
从上述示例中我们看到config结构体中的字段有不同的类型。也就是说可以将环境变量解析成不同的数据类型。
接下来,我们看看env包都支持哪些数据类型。
支持的数据类型
env包支持的数据类型如下:
- string
- bool
- int
- int8
- int16
- int32
- int64
- uint
- uint8
- uint16
- uint32
- uint64
- float32
- float64
- time.Duration
- encoding.TextUnmarshaler
- url.URL
当然,指针、切片、指针切片以及map这些数据类型也支持。同时,该包还支持通过自定义类型解析函数来支持自定义的数据类型。
自定义类型解析函数
如果你要解析的数据类型不是go内置的数据类型,那么你也可以通过自定义类型解析函数来进行解析。下面示例演示了如何将环境变量的值映射到自定一的MyTime类型字段上。如下:
代码语言:javascript复制type MyTime time.Time
func (t *MyTime) UnmarshalText(text []byte) error {
tt, err := time.Parse("2006-01-02", string(text))
*t = MyTime(tt)
return err
}
type Config struct {
SomeTime MyTime env:"SOME_TIME"
}
我们定义了一个MyTime类型,同时给这个类型定义了一个UnmarshalText方法。这样,在Config结构体中就可以将SOME_TIME的环境变量值解析到Config的SomeTime字段上。
从文件中解析环境变量
env包通过给结构体字段设置file标签就可以支持从文件中解析环境变量到结构体上。如下:
代码语言:javascript复制package main
import (
"fmt"
"time"
"github.com/caarlos0/env/v9"
)
type config struct {
Secret string env:"SECRET,file"
Password string env:"PASSWORD,file" envDefault:"/tmp/password"
Certificate string env:"CERTIFICATE,file,expand" envDefault:"${CERTIFICATE_FILE}"
}
func main() {
cfg := config{}
if err := env.Parse(&cfg); err != nil {
fmt.Printf("% vn", err)
}
fmt.Printf("% vn", cfg)
}
可以通过以下方式运行:
代码语言:javascript复制$ echo qwerty > /tmp/secret
$ echo dvorak > /tmp/password
$ echo coleman > /tmp/certificate
$ SECRET=/tmp/secret
CERTIFICATE_FILE=/tmp/certificate
go run main.go
{Secret:qwerty Password:dvorak Certificate:coleman}
如果需要了解更多该包的用处,请参考github上的官方文档:https://github.com/caarlos0/env