deepcopy.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. // deepcopy makes deep copies of things. A standard copy will copy the
  2. // pointers: deep copy copies the values pointed to. Unexported field
  3. // values are not copied.
  4. //
  5. // Copyright (c)2014-2016, Joel Scoble (github.com/mohae), all rights reserved.
  6. // License: MIT, for more details check the included LICENSE file.
  7. package deepcopy
  8. import (
  9. "errors"
  10. "reflect"
  11. "time"
  12. // _ "github.com/stretchr/testify/assert"
  13. )
  14. // Interface for delegating copy process to type
  15. type DeepCopyer interface {
  16. DeepCopy() interface{}
  17. }
  18. // // Iface is an alias to Copy; this exists for backwards compatibility reasons.
  19. // func Iface(iface interface{}) interface{} {
  20. // return Copy(iface)
  21. // }
  22. // Copy creates a deep copy of whatever is passed to it and returns the copy
  23. // in an interface{}. The returned value will need to be asserted to the
  24. // correct type.
  25. // 只支持常规类型的复制,例如:简单类型,时间,map,slice,array,指针,结构体及结构体
  26. // 不要用于有循环引用的数据
  27. // 多个指针指向同一个变量,复制后会生成多个
  28. // 未导出类型不复制;
  29. func Copy(src interface{}) interface{} {
  30. if src == nil {
  31. return nil
  32. }
  33. // Make the interface a reflect.Value
  34. original := reflect.ValueOf(src)
  35. // Make a copy of the same type as the original.
  36. cpy := reflect.New(original.Type()).Elem()
  37. // Recursively copy the original.
  38. deep := 0
  39. err := copyRecursive(original, cpy, deep)
  40. if err != nil {
  41. panic(err)
  42. }
  43. // Return the copy as an interface.
  44. return cpy.Interface()
  45. }
  46. // copyRecursive does the actual copying of the interface. It currently has
  47. // limited support for what it can handle. Add as needed.
  48. // 支持:简单类型,时间,map,slice,array,指针,结构体及结构体匿名变量;
  49. // 其他不支持(reflect.Chan, reflect.Func, reflect.Invalid, reflect.UnsafePointer)
  50. // 未导出类型不复制;
  51. // 多个指针指向同一个变量,复制后会生成多个
  52. // 不要用于有循环引用的数据,深度只能防死循环,不能防重复构造;
  53. // noCopy结构未处理
  54. // original 类型值
  55. // cpy 新类型值 指针的解引用
  56. func copyRecursive(original, cpy reflect.Value, deep int) error {
  57. deep += 1
  58. if deep > 20 {
  59. return errors.New("max deep")
  60. }
  61. // check for implement deepcopy.Interface
  62. if original.CanInterface() {
  63. if copier, ok := original.Interface().(DeepCopyer); ok {
  64. cpy.Set(reflect.ValueOf(copier.DeepCopy()))
  65. return nil
  66. }
  67. }
  68. // fmt.Println(original.Type().Name(), original.Type().String())
  69. var err error
  70. // handle according to original's Kind
  71. switch original.Kind() {
  72. case reflect.Ptr:
  73. // Get the actual value being pointed to.
  74. originalValue := original.Elem()
  75. // if it isn't valid, return.
  76. if !originalValue.IsValid() {
  77. return nil
  78. }
  79. cpy.Set(reflect.New(originalValue.Type()))
  80. err = copyRecursive(originalValue, cpy.Elem(), deep)
  81. case reflect.Interface:
  82. // If this is a nil, don't do anything
  83. if original.IsNil() {
  84. return nil
  85. }
  86. // Get the value for the interface, not the pointer.
  87. originalValue := original.Elem()
  88. // Get the value by calling Elem().
  89. copyValue := reflect.New(originalValue.Type()).Elem()
  90. err = copyRecursive(originalValue, copyValue, deep)
  91. cpy.Set(copyValue)
  92. case reflect.Struct:
  93. t, ok := original.Interface().(time.Time)
  94. if ok {
  95. cpy.Set(reflect.ValueOf(t))
  96. return nil
  97. }
  98. oriType := original.Type()
  99. if _, ok := oriType.FieldByName("noCopy"); ok {
  100. return nil
  101. }
  102. // Go through each field of the struct and copy it.
  103. num := original.NumField()
  104. for i := 0; i < num; i++ {
  105. if !oriType.Field(i).IsExported() {
  106. continue
  107. }
  108. err = copyRecursive(original.Field(i), cpy.Field(i), deep)
  109. if err != nil {
  110. break
  111. }
  112. }
  113. case reflect.Slice:
  114. if original.IsNil() {
  115. return nil
  116. }
  117. // Make a new slice and copy each element.
  118. cpy.Set(reflect.MakeSlice(original.Type(), original.Len(), original.Cap()))
  119. for i := 0; i < original.Len(); i++ {
  120. err = copyRecursive(original.Index(i), cpy.Index(i), deep)
  121. if err != nil {
  122. break
  123. }
  124. }
  125. case reflect.Map:
  126. if original.IsNil() {
  127. return nil
  128. }
  129. cpy.Set(reflect.MakeMap(original.Type()))
  130. for _, key := range original.MapKeys() {
  131. originalValue := original.MapIndex(key)
  132. copyValue := reflect.New(originalValue.Type()).Elem()
  133. err = copyRecursive(originalValue, copyValue, deep)
  134. if err != nil {
  135. break
  136. }
  137. copyKey := reflect.New(key.Type()).Elem()
  138. err = copyRecursive(key, copyKey, deep)
  139. if err != nil {
  140. break
  141. }
  142. cpy.SetMapIndex(copyKey, copyValue)
  143. }
  144. case reflect.Array:
  145. for i := 0; i < original.Len(); i++ {
  146. copyRecursive(original.Index(i), cpy.Index(i), deep)
  147. }
  148. case reflect.Uintptr, reflect.Chan, reflect.Func, reflect.Invalid, reflect.UnsafePointer:
  149. return nil
  150. default:
  151. cpy.Set(original)
  152. }
  153. return err
  154. }