英文:
Mapping Nested Config Yaml to struct
问题
我是你的中文翻译助手,以下是翻译好的内容:
我刚开始学习Go语言,并且正在使用viper加载所有的配置。我目前有一个YAML文件,内容如下:
countryQueries:
sg:
- qtype: gmap
qplacetype: postal_code
- qtype: gmap
qplacetype: address
- qtype: geocode
qplacetype: street_address
hk:
- qtype: gmap
qplacetype: postal_code
- qtype: gmap
qplacetype: address
- qtype: geocode
qplacetype: street_address
需要注意的是,countrycode是动态的,可以随时添加到任何国家。那么我该如何将其映射到一个结构体中,以便我可以按如下方式进行操作:
for _, query := range countryQueries["sg"] { }
我尝试通过循环来构建它,但是我在这里卡住了:
for country, queries := range viper.GetStringMap("countryQueries") {
// 我似乎无法对queries进行任何操作,我希望能够循环遍历它
for _, query := range queries {} // 这里报错
}
希望对你有帮助!
英文:
I'm new to go, and I'm using viper do load all my config what currently i have is the YAML look like below
countryQueries:
sg:
- qtype: gmap
qplacetype: postal_code
- qtype: gmap
qplacetype: address
- qtype: geocode
qplacetype: street_address
hk:
- qtype: gmap
qplacetype: postal_code
- qtype: gmap
qplacetype: address
- qtype: geocode
qplacetype: street_address
to note that the countrycode are dynamic it could be added anytime for any countries. So how do i map this to a struct where technically speaking i can do
for _, query := range countryQueries["sg"] { }
i try to contruct it myself by looping it but im stucked here
for country, queries := range viper.GetStringMap("countryQueries") {
// i cant seem to do anything with queries, which i wish to loop it
for _,query := range queries {} //here error
}
答案1
得分: 8
在阅读了一些资料后,我发现 viper 有自己的反序列化功能,非常好用。你可以在这里找到更多信息:https://github.com/spf13/viper#unmarshaling
这是我所做的:
type Configuration struct {
Countries map[string][]CountryQuery `mapstructure:"countryQueries"`
}
type CountryQuery struct {
QType string
QPlaceType string
}
func BuildConfig() {
viper.SetConfigName("configFileName")
viper.AddConfigPath("./config")
err := viper.ReadInConfig()
if err != nil {
panic(fmt.Errorf("Error config file: %s \n", err))
}
var config Configuration
err = viper.Unmarshal(&config)
if err != nil {
panic(fmt.Errorf("Unable to decode Config: %s \n", err))
}
}
希望对你有帮助!
英文:
After done some reading realized that viper has it own unmarshaling capabilities which works great https://github.com/spf13/viper#unmarshaling
So here what i did
type Configuration struct {
Countries map[string][]CountryQuery `mapstructure:"countryQueries"`
}
type CountryQuery struct {
QType string
QPlaceType string
}
func BuildConfig() {
viper.SetConfigName("configFileName")
viper.AddConfigPath("./config")
err := viper.ReadInConfig()
if err != nil {
panic(fmt.Errorf("Error config file: %s \n", err))
}
var config Configuration
err = viper.Unmarshal(&config)
if err != nil {
panic(fmt.Errorf("Unable to decode Config: %s \n", err))
}
}
答案2
得分: 1
这是一段使用go-yaml的简单代码:
package main
import (
"fmt"
"gopkg.in/yaml.v2"
"log"
)
var data = `
countryQueries:
sg:
- qtype: gmap
qplacetype: postal_code
- qtype: gmap
qplacetype: address
- qtype: geocode
qplacetype: street_address
hk:
- qtype: gmap
qplacetype: postal_code
- qtype: gmap
qplacetype: address
- qtype: geocode
qplacetype: street_address
`
func main() {
m := make(map[interface{}]interface{})
err := yaml.Unmarshal([]byte(data), &m)
if err != nil {
log.Fatalf("error: %v", err)
}
fmt.Printf("%v\n", m)
}
英文:
Here some simple code with go-yaml:
package main
import (
"fmt"
"gopkg.in/yaml.v2"
"log"
)
var data = `
countryQueries:
sg:
- qtype: gmap
qplacetype: postal_code
- qtype: gmap
qplacetype: address
- qtype: geocode
qplacetype: street_address
hk:
- qtype: gmap
qplacetype: postal_code
- qtype: gmap
qplacetype: address
- qtype: geocode
qplacetype: street_address
`
func main() {
m := make(map[interface{}]interface{})
err := yaml.Unmarshal([]byte(data), &m)
if err != nil {
log.Fatalf("error: %v", err)
}
fmt.Printf("%v\n", m)
}
答案3
得分: 1
如果你想将你的yaml
结构映射到一个严格的Go语言struct
,你可以使用mapstructure库来映射每个国家下的嵌套键值对。
例如:
package main
import (
"github.com/spf13/viper"
"github.com/mitchellh/mapstructure"
"fmt"
"log"
)
type CountryConfig struct {
Qtype string
Qplacetype string
}
type QueryConfig struct {
CountryQueries map[string][]CountryConfig
}
func NewQueryConfig() QueryConfig {
queryConfig := QueryConfig{}
queryConfig.CountryQueries = map[string][]CountryConfig{}
return queryConfig
}
func main() {
viper.SetConfigName("test")
viper.AddConfigPath(".")
err := viper.ReadInConfig()
queryConfig := NewQueryConfig()
if err != nil {
log.Panic("error:", err)
} else {
mapstructure.Decode(viper.AllSettings(), &queryConfig)
}
for _, config := range queryConfig.CountryQueries["sg"] {
fmt.Println("qtype:", config.Qtype, "qplacetype:", config.Qplacetype)
}
}
英文:
If you're looking to map your yaml
structure to a strict golang struct
you could make use of the mapstructure library to map the nested key/value pairs under each country.
For example:
package main
import (
"github.com/spf13/viper"
"github.com/mitchellh/mapstructure"
"fmt"
"log"
)
type CountryConfig struct {
Qtype string
Qplacetype string
}
type QueryConfig struct {
CountryQueries map[string][]CountryConfig;
}
func NewQueryConfig () QueryConfig {
queryConfig := QueryConfig{}
queryConfig.CountryQueries = map[string][]CountryConfig{}
return queryConfig
}
func main() {
viper.SetConfigName("test")
viper.AddConfigPath(".")
err := viper.ReadInConfig()
queryConfig := NewQueryConfig()
if err != nil {
log.Panic("error:", err)
} else {
mapstructure.Decode(viper.AllSettings(), &queryConfig)
}
for _, config := range queryConfig.CountryQueries["sg"] {
fmt.Println("qtype:", config.Qtype, "qplacetype:", config.Qplacetype)
}
}
答案4
得分: 0
你可以使用这个包 https://github.com/go-yaml/yaml 在Go语言中进行YAML的序列化和反序列化。
英文:
You can use this package https://github.com/go-yaml/yaml to serialize/deserialize YAML in Go.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论