123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- package util
- import (
- "fmt"
- "reflect"
- )
- func CopyStructSameField(dst interface{}, src interface{}) error {
- d := reflect.ValueOf(dst)
- if d.Kind() != reflect.Ptr {
- return fmt.Errorf("dst is not ptr")
- }
- d = d.Elem()
- if d.Kind() != reflect.Struct {
- return fmt.Errorf("dst is not struct")
- }
- s := reflect.ValueOf(src)
- if s.Kind() == reflect.Ptr {
- s = s.Elem()
- }
- if s.Kind() != reflect.Struct {
- return fmt.Errorf("src is not struct")
- }
- srcmap := map[string]reflect.Value{}
- numField := s.NumField()
- for i := 0; i < numField; i++ {
- srcmap[s.Type().Field(i).Name] = s.Field(i)
- }
- numField = d.NumField()
- for i := 0; i < numField; i++ {
- name := d.Type().Field(i).Name
- if v, ok := srcmap[name]; ok {
- if v.Type().Kind() == d.Type().Field(i).Type.Kind() {
- if v.Type().Kind() == reflect.Struct {
- CopyStructSameField(d.Field(i).Addr().Interface(), v.Interface())
- } else if v.Type().Kind() == reflect.Slice {
- d.Field(i).Set(reflect.MakeSlice(d.Field(i).Type(), 0, v.Len()))
- if t, err := CopySlice(d.Field(i).Interface(), v.Interface()); err == nil {
- tmp := reflect.ValueOf(t)
- d.Field(i).Set(reflect.MakeSlice(d.Field(i).Type(), tmp.Len(), tmp.Len()))
- reflect.Copy(d.Field(i), reflect.ValueOf(t))
- }
- } else {
- d.Field(i).Set(v)
- }
- }
- }
- }
- return nil
- }
- func CopySlice(dst interface{}, src interface{}) (ddd interface{}, err error) {
- d := reflect.ValueOf(dst)
- if d.Kind() == reflect.Ptr {
- d = d.Elem()
- }
- if d.Kind() != reflect.Slice {
- return dst, fmt.Errorf("dst is not slice")
- }
- s := reflect.ValueOf(src)
- if s.Kind() == reflect.Ptr {
- s = s.Elem()
- }
- if s.Kind() != reflect.Slice {
- return dst, fmt.Errorf("src is not slice")
- }
- count := s.Len()
- for i := 0; i < count; i++ {
- t := reflect.New(d.Type().Elem())
- if t.Type().Elem().Kind() == reflect.Struct && s.Index(i).Type().Kind() == reflect.Struct {
- CopyStructSameField(t.Interface(), s.Index(i).Interface())
- } else if t.Kind() == reflect.Slice && s.Index(i).Kind() == reflect.Slice {
- CopySlice(t, s.Field(i))
- } else if t.Kind() != reflect.Slice && t.Kind() != reflect.Struct && s.Index(i).Kind() != reflect.Slice && s.Index(i).Kind() != reflect.Struct {
- t.Set(s.Field(i))
- }
- d = reflect.Append(d, t.Elem())
- }
- return d.Interface(), nil
- }
|