英文:
Problem accessing nested YAML structure in Viper
问题
最近我尝试使用Viper和我的Cobra应用程序一起解析配置文件,但是发现无法解析内部嵌套块。ClustersOuter
的映射始终为空,我确定mapstructure的标签是正确的。我更喜欢使用Viper的Unmarshal功能而不是手动获取数据类型。
输出结果:
map[zones:[{ClustersOuter:map[] Id:1} {ClustersOuter:map[] Id:2}]]
不知何故,我似乎只能获取zone
映射及其ID,而无法获取clusters
映射的任何内容。
我的输入:
config.yml
zones:
- id: 1
clusters:
- cluster_id: 1
k3s_config_file: "k3s-cluster-1-config.yaml"
- cluster_id: 2
k3s_config_file: "k3s-cluster-2-config.yaml"
- cluster_id: 3
k3s_config_file: "k3s-cluster-3-config.yaml"
- id: 2
clusters:
- cluster_id: 1
k3s_config_file: "k3s-cluster-1-config.yaml"
- cluster_id: 2
k3s_config_file: "k3s-cluster-2-config.yaml"
- cluster_id: 3
k3s_config_file: "k3s-cluster-3-config.yaml"
configuration.go
package config
type Zones struct {
ClustersOuter map[string][]ClustersOuter `mapstructure:"zones"`
Id int `mapstructure:"id"`
}
type ClustersInner struct {
ClusterId int `mapstructure:"cluster_id"`
K3sConfigFile string `mapstructure:"k3s_config_file"`
}
type ClustersOuter struct {
ClustersInner map[string][]ClustersInner `mapstructure:"clusters"`
}
type ConfigSuper map[string][]Zones
main.go
viper.SetConfigName("config")
viper.AddConfigPath(".")
viper.SetConfigType("yaml")
if err := viper.ReadInConfig(); err != nil {
log.Fatalf("Error reading config file, %s", err)
return false
}
var configuration config.ConfigSuper
err := viper.Unmarshal(&configuration)
if err != nil {
log.Fatalf("unable to decode into struct, %v", err)
}
fmt.Printf("%+v\n", configuration)
英文:
Recently trying out Viper with my Cobra app to parse my config, but turned out that I couldn't parse the inner nested block. The map for ClustersOuter
is always empty, and I am sure the mapstructure is tagged correctly. I would prefer to use Viper Unmarshall feature rather than Getting the data type manually.
Output
map[zones:[{ClustersOuter:map[] Id:1} {ClustersOuter:map[] Id:2}]]
Somehow it seems like I can only retrieve the zone
map and its ID, but not any map for the clusters
map.
My inputs:
config.yml
zones:
- id: 1
clusters:
- cluster_id: 1
k3s_config_file: "k3s-cluster-1-config.yaml"
- cluster_id: 2
k3s_config_file: "k3s-cluster-2-config.yaml"
- cluster_id: 3
k3s_config_file: "k3s-cluster-3-config.yaml"
- id: 2
clusters:
- cluster_id: 1
k3s_config_file: "k3s-cluster-1-config.yaml"
- cluster_id: 2
k3s_config_file: "k3s-cluster-2-config.yaml"
- cluster_id: 3
k3s_config_file: "k3s-cluster-3-config.yaml"
configuration.go
package config
type Zones struct {
ClustersOuter map[string][]ClustersOuter `mapstructure:"zones"`
Id int `mapstructure:"id"`
}
type ClustersInner struct {
ClusterId int `mapstructure:"cluster_id"`
K3sConfigFile string `mapstructure:"k3s_config_file"`
}
type ClustersOuter struct {
ClustersInner map[string][]ClustersInner `mapstructure:"clusters"`
}
type ConfigSuper map[string][]Zones
main.go
viper.SetConfigName("config")
viper.AddConfigPath(".")
viper.SetConfigType("yaml")
if err := viper.ReadInConfig(); err != nil {
log.Fatalf("Error reading config file, %s", err)
return false
}
var configuration config.ConfigSuper
err := viper.Unmarshal(&configuration)
if err != nil {
log.Fatalf("unable to decode into struct, %v", err)
}
fmt.Printf("%+v\n", configuration)
答案1
得分: 3
你的结构类型与YAML类型不匹配,看起来你将映射和切片组合在一起,而实际上你只处理切片。在YAML中,映射的格式如下:
myMap:
key1: value1
而数组的格式如下:
myArray:
- foo: bar
不幸的是,你的配置对象混乱到我无法理解意图,所以我为你重新编写了它。这些类型可以被Viper解码而没有任何问题。
type Config struct {
Zones []Zone `mapstructure:"zones"`
}
type Zone struct {
ID int `mapstructure:"id"`
Clusters []Cluster `mapstructure:"clusters"`
}
type Cluster struct {
ClusterID int `mapstructure:"cluster_id"`
K3sConfigFile string `mapstructure:"k3s_config_file"`
}
Config
结构体是根对象,请确保解组到该结构体中。
config := Config{}
err = viper.Unmarshal(&config)
英文:
Your struct types do not reflect the YAML type, it looks like you've combined maps and slices together when you're only dealing with slices. In YAML, maps look like this:
myMap:
key1: value1
and arrays look like this:
myArray:
- foo: bar
Unfortunately, your config object is messed up enough that I can't understand the intent so I re-wrote it for you. These types can be decoded by Viper without any issues.
type Config struct {
Zones []Zone `mapstructure:"zones"`
}
type Zone struct {
ID int `mapstructure:"id"`
Clusters []Cluster `mapstructure:"clusters"`
}
type Cluster struct {
ClusterID int `mapstructure:"cluster_id"`
K3sConfigFile string `mapstructure:"k3s_config_file"`
}
The Config
struct is the root object, make sure to unmarshal into that.
config := Config{}
err = viper.Unmarshal(&config)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论