接口{}到[]字符串

Ole*_*ive 5 yaml go

我正在尝试将一些 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)

Ole*_*ive 5

感谢@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)