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