我正在尝试转换为map to struct,我差不多完成了,最后我遇到了问题,我无法将切片转换为struct:
func readDocTo(in bson.M, out reflect.Value) {
outt := out.Type()
outk := outt.Kind()
for {
if outk == reflect.Ptr && out.IsNil() {
out.Set(reflect.New(outt.Elem()))
}
if outk == reflect.Ptr {
out = out.Elem()
outt = out.Type()
outk = out.Kind()
continue
}
break
}
st := out.Type()
n := st.NumField()
for i := 0; i < n; i++ {
field := st.Field(i)
if field.PkgPath != "" {
continue // Private field
}
tag := field.Tag.Get("bson")
if tag == "" && strings.Index(string(field.Tag), ":") < 0 {
tag = string(field.Tag)
}
if tag == "-" {
continue
}
// XXX Drop this after a few releases.
if s := strings.Index(tag, "/"); s >= 0 {
recommend := tag[:s]
for _, c := range tag[s+1:] {
switch c {
case 'c':
recommend += ",omitempty"
case 's':
recommend += ",minsize"
default:
msg := fmt.Sprintf("Unsupported flag %q in tag %q of type %s", string([]byte{uint8(c)}), tag, st)
panic(externalPanic(msg))
}
}
msg := fmt.Sprintf("Replace tag %q in field %s of type %s by %q", tag, field.Name, st, recommend)
panic(externalPanic(msg))
}
if tag == "" {
tag = strings.ToLower(field.Name)
}
fieldt := field.Type
val, ok := in[tag]
switch fieldt.Kind() {
case reflect.Ptr:
if !ok {
out.Field(i).Set(reflect.New(fieldt.Elem()))
} else {
readDocTo(val.(bson.M), out.Field(i))
}
case reflect.String:
if ok {
out.Field(i).Set(reflect.ValueOf(val))
}
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
out.Field(i).SetInt(reflect.ValueOf(val).Int())
case reflect.Slice:
if ok {
s := reflect.ValueOf(val)
for j := 0; j < s.Len(); j++ {
item := s.Index(j)
fmt.Println(item.Interface().(bson.M))
fmt.Println(out.Field(i))
// TODO
// readDocTo(item.Interface().(bson.M), out.Field(i).Elem())
}
}
}
}
}