EqualPtrFields uses reflection to check two "mirror" structures for matching pointer fields that point to the same object. Used to verify cloning/deep copy functions. Returns the names of equal pointer fields.
(src, dst reflect.Value, prefix string)
| 12 | // |
| 13 | // Returns the names of equal pointer fields. |
| 14 | func EqualPtrFields(src, dst reflect.Value, prefix string) []string { |
| 15 | t := dst.Type() |
| 16 | if t.Kind() != reflect.Struct { |
| 17 | return nil |
| 18 | } |
| 19 | if srcType := src.Type(); srcType != t { |
| 20 | return nil |
| 21 | } |
| 22 | var res []string |
| 23 | for i := 0; i < t.NumField(); i++ { |
| 24 | srcF, dstF := src.Field(i), dst.Field(i) |
| 25 | switch f := t.Field(i); f.Type.Kind() { |
| 26 | case reflect.Ptr: |
| 27 | if srcF.Interface() == dstF.Interface() { |
| 28 | res = append(res, prefix+f.Name) |
| 29 | } |
| 30 | case reflect.Slice: |
| 31 | if srcF.Pointer() == dstF.Pointer() { |
| 32 | res = append(res, prefix+f.Name) |
| 33 | } |
| 34 | l := dstF.Len() |
| 35 | if srcLen := srcF.Len(); srcLen < l { |
| 36 | l = srcLen |
| 37 | } |
| 38 | for i := 0; i < l; i++ { |
| 39 | res = append(res, EqualPtrFields(srcF.Index(i), dstF.Index(i), f.Name+".")...) |
| 40 | } |
| 41 | case reflect.Struct: |
| 42 | res = append(res, EqualPtrFields(srcF, dstF, f.Name+".")...) |
| 43 | } |
| 44 | } |
| 45 | return res |
| 46 | } |