copy.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package utils
  2. import (
  3. "errors"
  4. "reflect"
  5. )
  6. func DeepFields(ifaceType reflect.Type) []reflect.StructField {
  7. var fields []reflect.StructField
  8. for i := 0; i < ifaceType.NumField(); i++ {
  9. v := ifaceType.Field(i)
  10. if v.Anonymous && v.Type.Kind() == reflect.Struct {
  11. fields = append(fields, DeepFields(v.Type)...)
  12. } else {
  13. fields = append(fields, v)
  14. }
  15. }
  16. return fields
  17. }
  18. func StructCopy(DstStructPtr interface{}, SrcStructPtr interface{}) error {
  19. srcv := reflect.ValueOf(SrcStructPtr)
  20. dstv := reflect.ValueOf(DstStructPtr)
  21. srct := reflect.TypeOf(SrcStructPtr)
  22. dstt := reflect.TypeOf(DstStructPtr)
  23. if srct.Kind() != reflect.Ptr || dstt.Kind() != reflect.Ptr ||
  24. srct.Elem().Kind() == reflect.Ptr || dstt.Elem().Kind() == reflect.Ptr {
  25. return errors.New("Fatal error:type of parameters must be Ptr of value")
  26. }
  27. if srcv.IsNil() || dstv.IsNil() {
  28. return errors.New("Fatal error:value of parameters should not be nil")
  29. }
  30. srcV := srcv.Elem()
  31. dstV := dstv.Elem()
  32. srcfields := DeepFields(reflect.ValueOf(SrcStructPtr).Elem().Type())
  33. for _, v := range srcfields {
  34. if v.Anonymous {
  35. continue
  36. }
  37. dst := dstV.FieldByName(v.Name)
  38. src := srcV.FieldByName(v.Name)
  39. if !dst.IsValid() {
  40. continue
  41. }
  42. if src.Type() == dst.Type() && dst.CanSet() {
  43. dst.Set(src)
  44. continue
  45. }
  46. if src.Kind() == reflect.Ptr && !src.IsNil() && src.Type().Elem() == dst.Type() {
  47. dst.Set(src.Elem())
  48. continue
  49. }
  50. if dst.Kind() == reflect.Ptr && dst.Type().Elem() == src.Type() {
  51. dst.Set(reflect.New(src.Type()))
  52. dst.Elem().Set(src)
  53. continue
  54. }
  55. }
  56. return nil
  57. }
  58. func FieldByTag(value reflect.Value, tag string, tagName string) reflect.Value {
  59. itype := value.Type()
  60. for i := 0; i < itype.NumField(); i++ {
  61. v := itype.Field(i)
  62. if v.Tag.Get(tagName) == tag && tag != "" {
  63. return value.FieldByIndex(v.Index)
  64. }
  65. }
  66. return reflect.Value{}
  67. }
  68. func StructCopyByTag(DstStructPtr interface{}, SrcStructPtr interface{}, tagName string) error {
  69. srcv := reflect.ValueOf(SrcStructPtr)
  70. dstv := reflect.ValueOf(DstStructPtr)
  71. srct := reflect.TypeOf(SrcStructPtr)
  72. dstt := reflect.TypeOf(DstStructPtr)
  73. if srct.Kind() != reflect.Ptr || dstt.Kind() != reflect.Ptr ||
  74. srct.Elem().Kind() == reflect.Ptr || dstt.Elem().Kind() == reflect.Ptr {
  75. return errors.New("Fatal error:type of parameters must be Ptr of value")
  76. }
  77. if srcv.IsNil() || dstv.IsNil() {
  78. return errors.New("Fatal error:value of parameters should not be nil")
  79. }
  80. srcV := srcv.Elem()
  81. dstV := dstv.Elem()
  82. srcfields := DeepFields(reflect.ValueOf(SrcStructPtr).Elem().Type())
  83. for _, v := range srcfields {
  84. if v.Anonymous {
  85. continue
  86. }
  87. dst := FieldByTag(dstV, v.Tag.Get(tagName), tagName)
  88. src := FieldByTag(srcV, v.Tag.Get(tagName), tagName)
  89. if !dst.IsValid() {
  90. continue
  91. }
  92. if src.Type() == dst.Type() && dst.CanSet() {
  93. dst.Set(src)
  94. continue
  95. }
  96. if src.Kind() == reflect.Ptr && !src.IsNil() && src.Type().Elem() == dst.Type() {
  97. dst.Set(src.Elem())
  98. continue
  99. }
  100. if dst.Kind() == reflect.Ptr && dst.Type().Elem() == src.Type() {
  101. dst.Set(reflect.New(src.Type()))
  102. dst.Elem().Set(src)
  103. continue
  104. }
  105. }
  106. return nil
  107. }