我将尝试将一些YAML文件解析为go结构体,但是文件本身不能被视为普通的go结构:一些值可能是字符串或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
}
我的域结构如下:
type Domain struct {
Host string
Urls []string
}
但是这段代码会导致错误:
invalid type assertion: v.MapIndex(host).([]string) (non-interface type reflect.Value on left)
所以我的问题可能听起来像“如何将{}接口转换为[]字符串?”或者它可能变得更加复杂:“如果某个键可以是简单字符串或map [string] [] string,如何将YAML文件解析为go结构?”
更新: 回应@mkopriva:
fmt.Println(v.MapIndex(host))
for url := range v.MapIndex(host).Interface().([] interface{}) {
fmt.Println(url)
}
对我没有帮助,因为它现在只打印一些整数(0),但实际上应该是一个字符串。将其转换为字符串数组会产生另一个错误:
panic: interface conversion: interface {} is []interface {}, not []string
reflect.Value.MapIndex
不会返回类型为interface{}
的值,而是返回类型为reflect.Value
的值,因此类型断言无法编译。reflect.Value
有一个名为Interface
的方法,它将其底层值作为interface{}
返回,您可以在其上进行类型断言。或者,您可以使用reflect.Value
的Kind
方法来确定接口的底层类型,然后从那里开始。 - mkopriva[]interface{}
强制转换为[]T
,您需要循环处理每个interface{}
项并单独进行断言。https://play.golang.org/p/tcig_e8o0bk - mkopriva无效的类型断言:url。(字符串)(左侧为非接口类型int)
- Alex Mokeevurl
不是接口,因此您不能对该值进行类型断言,正如我在第一条评论中已经提到的那样。它还告诉您实际类型是什么(int),因此如果您想将其存储为字符串,请使用strconv
包来完成。 - mkopriva