将嵌套配置Yaml映射到struct

时间:2017-01-13 09:14:24

标签: go struct config viper

我是新手,我正在使用viper加载我目前所拥有的所有配置是YAML如下所示

for /f "tokens=2 delims=:, " %%a in ('findstr /R /C:"\"electronVersion\":.*" %~dp0..\package.json') do set npm_config_target=%%~a

要注意国家/地区代码是动态的,可以随时添加到任何国家/地区。那么我如何将这个映射到一个技术上可以做的结构

 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

我尝试通过循环来自己构建它但是我被困在这里

for _, query := range countryQueries["sg"] { }

非常感谢任何帮助

4 个答案:

答案 0 :(得分:1)

如果您希望将yaml结构映射到严格的golang 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)
    }
}

答案 1 :(得分:1)

完成一些阅读后发现v蛇拥有自己的解组功能,效果很好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))
    }
}

答案 2 :(得分:0)

您可以使用此程序包https://github.com/go-yaml/yaml在Go中序列化/反序列化YAML。

答案 3 :(得分:0)

这里有一些简单的代码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)
}