我正在尝试将一些 YAML 文件解析为 go 结构,但文件本身不能被视为普通的 go 结构:某些值可能是 string 或 map[string][]string。
我尝试过的是自定义解组函数:
func (domain *Domain) UnmarshalYAML(unmarshal func(interface{}) error) error {
fmt.Println("Parsing domain")
var hostUrl interface{}
unmarshal(&hostUrl)
fmt.Println(reflect.TypeOf(hostUrl))
switch hostUrl.(type) {
case string:
domain.Host = hostUrl.(string)
case map[interface {}]interface {}:
fmt.Println("got map")
v := reflect.ValueOf(hostUrl)
fmt.Println(v.MapKeys()[0])
for _, host := range v.MapKeys() {
domain.Host = host.Interface().(string)
fmt.Println(v.MapIndex(host))
//HERE I NEED TO DO SMTH LIKE THIS:
//domain.Urls = v.MapIndex(host).([]string)
}
default:
return errors.New("invalid config file, cant parse domains")
}
return nil
}
Run Code Online (Sandbox Code Playgroud)
我的域结构如下所示:
type Domain struct {
Host string
Urls []string
}
Run Code Online (Sandbox Code Playgroud)
但这段代码会导致错误:
invalid type assertion: v.MapIndex(host).([]string) (non-interface type reflect.Value on left)
Run Code Online (Sandbox Code Playgroud)
所以我的问题可能听起来像“如何将 {}interface 转换为 []string?” 或者它可能会变得更复杂:“如果某个键可以是简单字符串或 map[string][]string,如何将 YAML 文件解析为 go 结构?”
更新:回复@mkopriva:
fmt.Println(v.MapIndex(host))
for url := range v.MapIndex(host).Interface().([] interface{}) {
fmt.Println(url)
}
Run Code Online (Sandbox Code Playgroud)
没有帮助我,因为现在它只打印一些整数(0),但应该有一个字符串。将其转换为字符串数组会引发另一个错误:
panic: interface conversion: interface {} is []interface {}, not []string
Run Code Online (Sandbox Code Playgroud)
感谢@mkopriva 和沙箱中的片段。迭代过程中出现整数的原因v.MapIndex(host).Interface().([] interface{})
是 range 返回两个值:index 和对应于该索引值。我只抓到了第一个。这就是为什么我无法将其转换为字符串。
工作循环:
for _, url := range v.MapIndex(host).Interface().([] interface{}) {
fmt.Println(url.(string))
domain.Urls = append(domain.Urls,url.(string) )
}
Run Code Online (Sandbox Code Playgroud)