1

我正在尝试完成一个非常简单的示例,其中我使用viper从环境变量加载配置。我已经通过 将它安装在我的项目中go get github.com/spf13/viper,并且依赖项在我的go.mod

module github.com/naftulikay/viper-demo

go 1.16

require github.com/spf13/viper v1.7.1 // indirect

这是我的代码,它可以编译并运行:

package main

import (
    "fmt"
    "github.com/spf13/viper"
)

var config Config

type Config struct {
    MyString string //`mapstructure:"MY_STRING"`
}

func main() {
    v := viper.New()
    v.AutomaticEnv()

    var err error

    err = v.Unmarshal(&config)

    if err != nil {
        fmt.Printf("Unable to load config: %s\n", err)
    }

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

我正在设置环境变量以尝试测试环境变量名称的不同排列

MY_STRING=a my_string=b MyString=c ./viper-demo

我尝试了很多不同的方法,删除mapstructure注释,更改其值等,但执行时得到的只是:

&{MyString:}

我正在按照自述文件以及我在网上找到的其他演示中的说明进行操作,似乎viper没有加载环境变量。

我觉得这是一个非常简单的例子,我的要求是将配置映射到结构,并从环境变量中获取该配置。我最终可能会开始做 CLI 标志和配置文件,但是环境变量对我来说是成败,我需要它们才能工作。

我错过了什么?

4

1 回答 1

0

这似乎是一个长期存在的问题,几年来[1]。但是,在该线程中,建议您可以使用BindEnv[2]:

package main

import (
    "fmt"
    "github.com/spf13/viper"
)

func main() {
   var c struct {
      TMP string
   }
   v := viper.New()
   v.AutomaticEnv()
   v.BindEnv("TMP")
   v.Unmarshal(&c)
   fmt.Printf("%+v\n", &c)
}

对于另一种方法,您可以使用os.Environ[3]:

package main

import (
   "fmt"
   "os"
   "strings"
)

func environ() map[string]string {
   m := make(map[string]string)
   for _, s := range os.Environ() {
      a := strings.Split(s, "=")
      m[a[0]] = a[1]
   }
   return m
}

func main() {
   m := environ()
   fmt.Printf("%q\n", m)
}
  1. https://github.com/spf13/viper/issues/188
  2. https://pkg.go.dev/github.com/spf13/viper#Viper.BindEnv
  3. https://golang.org/pkg/os#Environ
于 2021-05-19T20:01:12.317 回答