我在这里使用了优秀的viper库:https://github.com/spf13/viper
我正在尝试读取hcl中的一个配置文件(尽管它也可以是一个JSOn或YAML文件),它看起来像这样:
interval = 10
statsd_prefix = "pinger"
group "dns" {
target_prefix = "ping"
target "dns" {
hosts = [
"dnsserver1",
"dnsserver2"
]
}
}
到目前为止,我得到的代码如下所示:
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
函数。转储后的结果结构如下所示:
([]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完全陌生,所以请对我手下留情:)
发布于 2016-08-15 23:26:05
不是调用raw Get,然后再决定你到底得到了什么,我建议首先描述你想要的配置结构,例如
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"`
}
然后在其中进行解包(解码)
var C config
err := viper.Unmarshal(&C)
if err != nil {
t.Fatalf("unable to decode into struct, %v", err)
}
假设解码器足够聪明,在可能和有意义的情况下,解码器应该在提供的结构中解锁。
发布于 2020-06-19 04:19:15
这个问题有点老了,但我想既然我偶然发现了这一点,其他人可能会来这里寻找……
原始问题中的主要问题是,这种JSON表示法定义了一个列表,而不是一个映射:
hosts = [
"dnsserver1",
"dnsserver2"
]
因此,本例中的简单解决方案不是使用viper.GetStringMap("group")
,而是使用viper.GetStringSlice("group")
。
GO中的切片是大多数其他编程语言所称的数组或列表。因此,在本例中,切片将为["dnsserver1", "dnsserver2"]
。
如果您希望正确使用viper的GetStringMap()
函数,则需要在配置文件中使用不同的格式,即映射格式:
"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“的字符串。
https://stackoverflow.com/questions/38955605
复制相似问题