struct.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package util
  2. import (
  3. "fmt"
  4. "reflect"
  5. )
  6. func CopyStructSameField(dst interface{}, src interface{}) error {
  7. d := reflect.ValueOf(dst)
  8. if d.Kind() != reflect.Ptr {
  9. return fmt.Errorf("dst is not ptr")
  10. }
  11. d = d.Elem()
  12. if d.Kind() != reflect.Struct {
  13. return fmt.Errorf("dst is not struct")
  14. }
  15. s := reflect.ValueOf(src)
  16. if s.Kind() == reflect.Ptr {
  17. s = s.Elem()
  18. }
  19. if s.Kind() != reflect.Struct {
  20. return fmt.Errorf("src is not struct")
  21. }
  22. srcmap := map[string]reflect.Value{}
  23. numField := s.NumField()
  24. for i := 0; i < numField; i++ {
  25. srcmap[s.Type().Field(i).Name] = s.Field(i)
  26. }
  27. numField = d.NumField()
  28. for i := 0; i < numField; i++ {
  29. name := d.Type().Field(i).Name
  30. if v, ok := srcmap[name]; ok {
  31. if v.Type().Kind() == d.Type().Field(i).Type.Kind() {
  32. if v.Type().Kind() == reflect.Struct {
  33. CopyStructSameField(d.Field(i).Addr().Interface(), v.Interface())
  34. } else if v.Type().Kind() == reflect.Slice {
  35. d.Field(i).Set(reflect.MakeSlice(d.Field(i).Type(), 0, v.Len()))
  36. if t, err := CopySlice(d.Field(i).Interface(), v.Interface()); err == nil {
  37. tmp := reflect.ValueOf(t)
  38. d.Field(i).Set(reflect.MakeSlice(d.Field(i).Type(), tmp.Len(), tmp.Len()))
  39. reflect.Copy(d.Field(i), reflect.ValueOf(t))
  40. }
  41. } else {
  42. d.Field(i).Set(v)
  43. }
  44. }
  45. }
  46. }
  47. return nil
  48. }
  49. func CopySlice(dst interface{}, src interface{}) (ddd interface{}, err error) {
  50. d := reflect.ValueOf(dst)
  51. if d.Kind() == reflect.Ptr {
  52. d = d.Elem()
  53. }
  54. if d.Kind() != reflect.Slice {
  55. return dst, fmt.Errorf("dst is not slice")
  56. }
  57. s := reflect.ValueOf(src)
  58. if s.Kind() == reflect.Ptr {
  59. s = s.Elem()
  60. }
  61. if s.Kind() != reflect.Slice {
  62. return dst, fmt.Errorf("src is not slice")
  63. }
  64. count := s.Len()
  65. for i := 0; i < count; i++ {
  66. t := reflect.New(d.Type().Elem())
  67. if t.Type().Elem().Kind() == reflect.Struct && s.Index(i).Type().Kind() == reflect.Struct {
  68. CopyStructSameField(t.Interface(), s.Index(i).Interface())
  69. } else if t.Kind() == reflect.Slice && s.Index(i).Kind() == reflect.Slice {
  70. CopySlice(t, s.Field(i))
  71. } else if t.Kind() != reflect.Slice && t.Kind() != reflect.Struct && s.Index(i).Kind() != reflect.Slice && s.Index(i).Kind() != reflect.Struct {
  72. t.Set(s.Field(i))
  73. }
  74. d = reflect.Append(d, t.Elem())
  75. }
  76. return d.Interface(), nil
  77. }