0

我用毒蛇。我正在尝试使用 yml-config 从结构中获取信息。

type Config struct {
    Account       User           `mapstructure:"user"`      
}

type User struct {
    Name       string           `mapstructure:"name"`
    Contacts   []Contact        `mapstructure:"contact"`
}

type Contact struct {
    Type          string          `mapstructure:"type"`
    Value         string          `mapstructure:"value"`
}

func Init() *Config {
    conf := new(Config)

    viper.SetConfigType("yaml")
    viper.ReadInConfig()
    ...
    viper.Unmarshal(conf)
    return conf
}

...
config := Init()
...
for _, contact := range config.Account.Contacts {
   type := contact.type
   vlaue := contact.value
}

和 config.yml

user:
  name: John
  contacts:
    email:
      type: email
      value: test@test.com
    skype:
      type: skype
      value: skypeacc

我可以得到这样的结构物品吗?我无法获得这样的联系数据。可能吗?

4

2 回答 2

0

如果我正确地实现了您想要实现的目标,并且基于for您提供的循环;

  • 你真正需要的是一个 YAML序列,它是一个数组。所以你最终的 YAML 文件应该是这样的;
user:
  name: John
  contacts:
      - type: email
        value: test@test.com
      - type: skype
        value: skypeacc
      - type: email
        value: joe@example.com
  • 此外,您的Contacts切片标签中有错字。它应该与 YAML 键匹配;
type User struct {
   Name     string    `mapstructure:"name"`
   Contacts []Contact `mapstructure:"contacts"`
}

如果您希望保留原始 YAML 文件结构,则必须为每个 YAML 键提供一个标签(和相应的结构字段),因此无法开箱即用地循环它,因为emailskype被解析为结构字段。原始 YAML 文件的结构示例如下:

type Config struct {
    Account User `mapstructure:"user"`
}

type User struct {
    Name     string   `mapstructure:"name"`
    Contacts Contacts `mapstructure:"contacts"`
}

type Contacts struct {
    Email Contact `mapstructure:"email"`
    Skype Contact `mapstructure:"skype"`
}

type Contact struct {
    Type  string `mapstructure:"type"`
    Value string `mapstructure:"value"`
}
于 2021-07-17T18:45:44.643 回答
0

我认为唯一重要的问题是在您的数据结构中您已声明Contacts为列表,但在您的 YAML 文件中它是字典。如果您像这样构造输入文件:

user:
  name: John
  contacts:
    - type: email
      value: test@test.com
    - type: skype
      value: skypeacc

然后你可以这样读:

package main

import (
    "fmt"

    "github.com/spf13/viper"
)

type Config struct {
    User User
}

type User struct {
    Name     string
    Contacts []Contact
}

type Contact struct {
    Type  string
    Value string
}

func main() {
    var cfg Config

    viper.SetConfigName("config")
    viper.AddConfigPath(".")
    err := viper.ReadInConfig()
    if err != nil {
        panic(err)
    }
    viper.Unmarshal(&cfg)
    fmt.Println("user: ", cfg.User.Name)
    for _, contact := range cfg.User.Contacts {
        fmt.Println("  ", contact.Type, ": ", contact.Value)
    }
}

上面的代码可以按原样运行;您应该能够将其放入文件中并构建它。当我运行上面的例子时,我得到了输出:

user:  John
   email :  test@test.com
   skype :  skypeacc
于 2021-07-17T19:17:51.273 回答