如何使用结构迭代 yml 部分?
How to iterate over yml sections with structs?
我用毒蛇。我正在尝试使用 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 sequence,它是一个 array。所以你最终的 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 密钥提供一个标签(和相应的结构字段),所以循环它不可能开箱即用,因为 email
和 skype
被解析为结构字段。原始 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"`
}
我认为唯一重要的问题是,在您的数据结构中,您已将 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
我用毒蛇。我正在尝试使用 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 sequence,它是一个 array。所以你最终的 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 密钥提供一个标签(和相应的结构字段),所以循环它不可能开箱即用,因为 email
和 skype
被解析为结构字段。原始 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"`
}
我认为唯一重要的问题是,在您的数据结构中,您已将 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