首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Golang Viper读取地图切片

使用Golang Viper读取地图切片
EN

Stack Overflow用户
提问于 2016-08-15 21:01:39
回答 2查看 12.2K关注 0票数 4

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

我正在尝试读取hcl中的一个配置文件(尽管它也可以是一个JSOn或YAML文件),它看起来像这样:

代码语言:javascript
运行
复制
interval = 10
statsd_prefix = "pinger"



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

到目前为止,我得到的代码如下所示:

代码语言:javascript
运行
复制
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)

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

当我使用viper.GetStringMap读取它时,它似乎不起作用,所以我使用了标准的viper.Get函数。转储后的结果结构如下所示:

代码语言:javascript
运行
复制
([]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"
        }
       }
      }
     }
    }
   }
  }
 }
}

当我使用反射时,它似乎是slice类型。我需要把它切成薄片吗?我该怎么做?有没有更简单的方法来管理这样的数据结构?

我对golang完全陌生,所以请对我手下留情:)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-15 23:26:05

不是调用raw Get,然后再决定你到底得到了什么,我建议首先描述你想要的配置结构,例如

代码语言:javascript
运行
复制
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"`
}

然后在其中进行解包(解码)

代码语言:javascript
运行
复制
var C config

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

假设解码器足够聪明,在可能和有意义的情况下,解码器应该在提供的结构中解锁。

票数 9
EN

Stack Overflow用户

发布于 2020-06-19 04:19:15

这个问题有点老了,但我想既然我偶然发现了这一点,其他人可能会来这里寻找……

原始问题中的主要问题是,这种JSON表示法定义了一个列表,而不是一个映射:

代码语言:javascript
运行
复制
hosts = [
      "dnsserver1",
      "dnsserver2"
    ]

因此,本例中的简单解决方案不是使用viper.GetStringMap("group"),而是使用viper.GetStringSlice("group")

GO中的切片是大多数其他编程语言所称的数组或列表。因此,在本例中,切片将为["dnsserver1", "dnsserver2"]

如果您希望正确使用viper的GetStringMap()函数,则需要在配置文件中使用不同的格式,即映射格式:

代码语言:javascript
运行
复制
"hosts": {
    "dnsserver1": "8.8.8.8",
    "dnsserver2": "8.8.4.4"
  }

然后可以使用viper.GetStringMap()将其解析为map[string]string结构,如下所示:map["dnsserver1":"8.8.8.8" "dnsserver2":"8.8.4.4"]。然后,您可以通过给定的键访问映射,比如map["dnsserver1"],它会给出一个包含"8.8.8.8“的字符串。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38955605

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档