golang基于标签的环境变量配置插件库env的使用

golang基于标签的环境变量配置插件库env的使用

env 是一个基于标签的环境变量配置库,用于将环境变量映射到 Go 结构体字段。

安装

$ go get -u github.com/codingconcepts/env

使用示例

下面是一个完整的使用示例:

package main

import (
	"fmt"
	"log"
	"time"

	"github.com/codingconcepts/env"
)

// 定义配置结构体,使用env标签指定环境变量名
type config struct {
	Secret            []byte        `env:"SECRET" required:"true"`  // 必填字段
	Region            string        `env:"REGION"`                 // 可选字段
	Port              int           `env:"PORT" required:"true"`   // 必填字段
	Peers             []string      `env:"PEERS"`                  // 数组类型,默认使用逗号分隔
	ConnectionTimeout time.Duration `env:"TIMEOUT" default:"10s"`  // 带默认值的字段
}

func main() {
	c := config{}
	
	// 将环境变量映射到结构体
	if err := env.Set(&c); err != nil {
		log.Fatal(err)
	}

	// 打印配置
	fmt.Printf("Secret: %s\n", c.Secret)
	fmt.Printf("Region: %s\n", c.Region)
	fmt.Printf("Port: %d\n", c.Port)
	fmt.Printf("Peers: %v\n", c.Peers)
	fmt.Printf("ConnectionTimeout: %v\n", c.ConnectionTimeout)
}

运行程序时可以这样设置环境变量:

$ SECRET=mysecret PORT=8080 PEERS=peer1,peer2,peer3 TIMEOUT=5s go run main.go

支持的字段类型

env 库支持以下字段类型:

  • bool[]bool
  • string[]string
  • []byte
  • int, int8, int16, int32, int64, []int, []int8, []int16, []int32, 和 []int64
  • uint, uint8, uint16, uint32, uint64, []uint, []uint8, []uint16, []uint32, 和 []uint64
  • float32, float64, []float32, 和 []float64
  • time.Duration[]time.Duration

高级用法

对于数组类型,可以使用 delimiter 标签指定分隔符:

type config struct {
	Peers []string `env:"PEERS" delimiter:" "` // 使用空格作为分隔符
}

这样设置环境变量时可以使用空格分隔:

$ PEERS="peer1 peer2 peer3" go run main.go

更多关于golang基于标签的环境变量配置插件库env的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang基于标签的环境变量配置插件库env的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang 基于标签的环境变量配置插件库 env 使用指南

env 是一个流行的 Golang 库,它通过结构体标签 (struct tags) 来简化环境变量的解析和绑定。下面我将详细介绍如何使用这个库。

安装

首先安装 env 库:

go get github.com/caarlos0/env/v9

基本用法

package main

import (
	"fmt"
	"log"
	"time"

	"github.com/caarlos0/env/v9"
)

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 {
		log.Fatal(err)
	}

	fmt.Printf("%+v\n", cfg)
}

特性详解

1. 基本类型支持

env 支持所有基本 Go 类型:

  • string
  • bool
  • int, int8, int16, int32, int64
  • uint, uint8, uint16, uint32, uint64
  • float32, float64
  • time.Duration
  • []string, []int, []bool 等切片类型

2. 默认值

使用 envDefault 标签指定默认值:

type config struct {
    Port int `env:"PORT" envDefault:"8080"`
}

3. 必填字段

添加 required 标签使字段成为必填项:

type config struct {
    ApiKey string `env:"API_KEY,required"`
}

4. 切片类型

对于切片类型,可以使用 envSeparator 指定分隔符:

type config struct {
    Hosts []string `env:"HOSTS" envSeparator:":"` // 读取 "host1:host2:host3"
}

5. 嵌套结构体

env 支持嵌套结构体:

type config struct {
    Database struct {
        Host     string `env:"DB_HOST" envDefault:"localhost"`
        Port     int    `env:"DB_PORT" envDefault:"5432"`
        User     string `env:"DB_USER" envDefault:"postgres"`
        Password string `env:"DB_PASSWORD" envDefault:""`
    }
    Cache struct {
        Enabled bool `env:"CACHE_ENABLED" envDefault:"false"`
        TTL     int  `env:"CACHE_TTL" envDefault:"30"`
    }
}

6. 自定义解析器

可以注册自定义类型解析器:

type myType string

func (mt *myType) UnmarshalText(text []byte) error {
    *mt = myType("custom:" + string(text))
    return nil
}

type config struct {
    MyVar myType `env:"MY_VAR"`
}

func main() {
    cfg := config{}
    if err := env.ParseWithOptions(&cfg, env.Options{
        FuncMap: map[reflect.Type]env.ParserFunc{
            reflect.TypeOf(myType("")): func(v string) (interface{}, error) {
                var mt myType
                return mt, mt.UnmarshalText([]byte(v))
            },
        },
    }); err != nil {
        log.Fatal(err)
    }
}

7. 环境变量扩展

使用 envExpand 标签可以扩展环境变量中的变量:

type config struct {
    Path string `env:"PATH" envExpand:"true"`
}

高级选项

选项配置

opts := env.Options{
    Environment: map[string]string{
        "DATABASE_URL": "postgres://localhost:5432",
    },
    TagName: "env", // 默认就是 "env"
    RequiredIfNoDef: true, // 如果没有默认值则必须提供
    OnSet: func(tag string, value interface{}, isDefault bool) {
        fmt.Printf("Set %s to %v (default? %v)\n", tag, value, isDefault)
    },
}

cfg := config{}
if err := env.ParseWithOptions(&cfg, opts); err != nil {
    log.Fatal(err)
}

前缀处理

可以为所有环境变量添加前缀:

type config struct {
    Home string `env:"HOME"`
}

func main() {
    cfg := config{}
    if err := env.ParseWithOptions(&cfg, env.Options{
        Prefix: "MYAPP_",
    }); err != nil {
        log.Fatal(err)
    }
    // 会查找 MYAPP_HOME 环境变量
}

最佳实践

  1. 集中管理配置:将所有环境变量配置集中在一个结构体中
  2. 使用默认值:为可选参数提供合理的默认值
  3. 标记必填项:对关键配置使用 required 标签
  4. 文档化:在结构体注释中说明每个环境变量的用途
  5. 测试配置:编写测试验证配置是否正确加载

完整示例

package main

import (
	"fmt"
	"log"
	"time"

	"github.com/caarlos0/env/v9"
)

// Config 定义应用配置
type Config struct {
	// 服务器配置
	Server struct {
		Host        string        `env:"SERVER_HOST" envDefault:"0.0.0.0"`
		Port        int           `env:"SERVER_PORT" envDefault:"8080"`
		Timeout     time.Duration `env:"SERVER_TIMEOUT" envDefault:"30s"`
		Debug       bool          `env:"SERVER_DEBUG" envDefault:"false"`
		AllowedIPs  []string      `env:"SERVER_ALLOWED_IPS" envSeparator:","`
	}

	// 数据库配置
	Database struct {
		URL      string `env:"DB_URL" envDefault:"postgres://localhost:5432"`
		Username string `env:"DB_USER" envDefault:"postgres"`
		Password string `env:"DB_PASSWORD,required"`
		PoolSize int    `env:"DB_POOL_SIZE" envDefault:"10"`
	}

	// 第三方服务
	ExternalAPI struct {
		Endpoint string `env:"API_ENDPOINT" envDefault:"https://api.example.com"`
		Key      string `env:"API_KEY,required"`
		Retries  int    `env:"API_RETRIES" envDefault:"3"`
	}
}

func main() {
	var cfg Config
	if err := env.Parse(&cfg); err != nil {
		log.Fatalf("Failed to parse config: %v", err)
	}

	fmt.Printf("Server Config: %+v\n", cfg.Server)
	fmt.Printf("Database Config: %+v\n", cfg.Database)
	fmt.Printf("External API Config: %+v\n", cfg.ExternalAPI)
}

env 库通过结构体标签提供了简洁而强大的环境变量管理方式,非常适合在 Go 应用程序中处理配置。

回到顶部