问题描述
我正在尝试完成一个非常简单的示例,其中我使用 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 标志和配置文件,但环境变量对我来说是成败的,我需要它们才能工作。
我错过了什么?
解决方法
这似乎是一个长期存在的问题,已经持续了好几年 [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)
}