用Golang Viper阅读一片地图 [英] Reading a slice of maps with Golang Viper

查看:331
本文介绍了用Golang Viper阅读一片地图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从这里使用优秀的viper库: https://github.com/spf13/viper



我试图读取hcl中的配置文件(虽然它也可能是JSOn或YAML文件),它看起来像这样:

  interval = 10 
statsd_prefix =pinger



组dns{
target_prefix =ping
targetdns{
hosts = [
dnsserver1,
dnsserver2
]


我到目前为止的代码如下所示: p>

  viper.SetConfigName(config)
viper.AddConfigPath(。)

err:= viper.ReadInConfig()

if err!= nil {
panic(fmt.Errorf(致命错误配置文件:%s \ n,err))


interval:= viper.GetInt(interval)
prefix:= viper.GetString(statsd_prefix)

groups:= viper。 GetStringMap(group)

fmt。 Println(间隔)
fmt.Println(前缀)

我遇到的大问题是与组选项。这可以是多个不同的组。



当我使用 viper.GetStringMap ,所以我使用了标准的 viper.Get 函数。转储后的结果如下所示:

 ([] map [string] interface {})(len = 1 cap = 1){
(map [string] interface {})(len = 1){
(string)(len = 3)dns:([] map [string] interface {})( len = 1 cap = 2){
(map [string] interface {})(len = 2){
(string)(len = 13)target_prefix:(字符串) )ping,
(string)(len = 6)target:([] map [string] interface {})(len = 1 cap = 1){
(map [string]接口{})(len = 1){
(string)(len = 8)dns:([] map [string] interface {})(len = 1 cap = 1){
(map [string] interface {})(len = 1){
(string)(len = 5)hosts:([] interface {})(len = 2 cap = 2){
(string)(len = 18)dnsserver1,
(string)(len = 18)dnsserver2
}
}
}
}









<当我使用反射时,它似乎是类型切片。我需要将它投射到切片上吗?我怎么做?有没有更简单的方式来管理这样的数据结构?



我对golang完全陌生,所以请在我身上轻松一下:)

解决方案

而不是调用原始的获取,然后决定到底是什么,我建议先描述一下你想要的配置结构,比如

 类型配置结构{
间隔int`地图结构:间隔
statsdPrefix字符串`地图结构:statsd_prefix`
groups [] group
}
type group struct {
group string`mapstructure:group`
targetPrefix string`mapstructure:target_prefix`
targets []目标
}
类型目标结构{
目标字符串`地图结构:目标`
主机[]字符串`地图结构:主机`
}

而不是unmarshall(解码)

 var C config 

err:= viper.Unmarshal(& C)
if err!= nil {
t.Fatalf( unabl假设解码器是智能的,则解码为struct,%v,err)
}

足以在所提供的结构中解开,如果可能和有意义的话。


I'm using the excellent viper library from here: https://github.com/spf13/viper

I'm trying to read in a config file in hcl (although it could be a JSOn or YAML file as well) which looks like this:

interval = 10
statsd_prefix = "pinger"



group "dns" {
  target_prefix = "ping"
  target "dns" {
    hosts = [
      "dnsserver1",
      "dnsserver2"
    ]
  }
}

The code I have so far looks like this:

viper.SetConfigName("config")
viper.AddConfigPath(".")

err := viper.ReadInConfig()

if err != nil {
  panic(fmt.Errorf("Fatal error config file: %s \n", err))
}

interval := viper.GetInt("interval")
prefix := viper.GetString("statsd_prefix")

groups := viper.GetStringMap("group")

fmt.Println(interval)
fmt.Println(prefix)

The big problem I'm having is with the group option. This can be multiple different groups.

It doesn't seem to work when I read it in using viper.GetStringMap, so I used the standard viper.Get function. The resulting structure looks like this when dumped:

([]map[string]interface {}) (len=1 cap=1) {
 (map[string]interface {}) (len=1) {
  (string) (len=3) "dns": ([]map[string]interface {}) (len=1 cap=2) {
   (map[string]interface {}) (len=2) {
    (string) (len=13) "target_prefix": (string) (len=4) "ping",
    (string) (len=6) "target": ([]map[string]interface {}) (len=1 cap=1) {
     (map[string]interface {}) (len=1) {
      (string) (len=8) "dns": ([]map[string]interface {}) (len=1 cap=1) {
       (map[string]interface {}) (len=1) {
        (string) (len=5) "hosts": ([]interface {}) (len=2 cap=2) {
         (string) (len=18) "dnsserver1",
         (string) (len=18) "dnsserver2"
        }
       }
      }
     }
    }
   }
  }
 }
}

It seems to be of type slice when I use reflect. Do I need to cast it to a slice? How do I do that? Is there an easier way of managing a data structure like this?

I'm completely new to golang, so please go easy on me :)

解决方案

Instead of call raw Get and then decide what exactly you get I'd suggest first describe your desired config structure, something like

type config struct {
    interval int `mapstructure:"Interval"`
    statsdPrefix string `mapstructure:"statsd_prefix"`
    groups []group
}
type group struct {
    group string `mapstructure:"group"`
    targetPrefix string `mapstructure:"target_prefix"`
    targets []target
}
type target struct {
    target string `mapstructure:"target"`
    hosts []string `mapstructure:"hosts"`
}

and than unmarshall(decode) in it

var C config

err := viper.Unmarshal(&C)
if err != nil {
    t.Fatalf("unable to decode into struct, %v", err)
}

assuming decoder is smart enough to unmurshall in provided structure if it possible and meaningful.

这篇关于用Golang Viper阅读一片地图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆