微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用结构迭代 yml 部分?

如何解决如何使用结构迭代 yml 部分?

我使用毒蛇。我正在尝试使用 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

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

解决方法

如果我根据您提供的 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 键提供一个标签(和相应的结构字段),因此不可能开箱即用地循环遍历它,因为 {{1} } 和 email 被解析为结构体字段。原始 YAML 文件的结构示例是;

skype
,

我认为唯一重要的问题是,在您的数据结构中,您已将 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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。