1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| func ToMap2(in interface{}, tag string) (map[string]interface{}, error) {
v := reflect.ValueOf(in) if v.Kind() == reflect.Ptr { v = v.Elem() } if v.Kind() != reflect.Struct { return nil, fmt.Errorf("ToMap only accepts struct or struct pointer; got %T", v) }
out := make(map[string]interface{}) queue := make([]interface{}, 0, 1) queue = append(queue, in)
for len(queue) > 0 { v := reflect.ValueOf(queue[0]) if v.Kind() == reflect.Ptr { v = v.Elem() } queue = queue[1:] t := v.Type() for i := 0; i < v.NumField(); i++ { vi := v.Field(i) if vi.Kind() == reflect.Ptr { vi = vi.Elem() if vi.Kind() == reflect.Struct { queue = append(queue, vi.Interface()) } else { ti := t.Field(i) if tagValue := ti.Tag.Get(tag); tagValue != "" { out[tagValue] = vi.Interface() } } break } if vi.Kind() == reflect.Struct { queue = append(queue, vi.Interface()) break } ti := t.Field(i) if tagValue := ti.Tag.Get(tag); tagValue != "" { out[tagValue] = vi.Interface() } } } return out, nil }
|