mirror of
https://github.com/duanhf2012/origin.git
synced 2026-02-15 08:14:46 +08:00
提交origin2.0版本
This commit is contained in:
73
util/deepcopy/deepcopy.go
Normal file
73
util/deepcopy/deepcopy.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package deepcopy
|
||||
|
||||
import "reflect"
|
||||
|
||||
func deepCopy(dst, src reflect.Value) {
|
||||
switch src.Kind() {
|
||||
case reflect.Interface:
|
||||
value := src.Elem()
|
||||
if !value.IsValid() {
|
||||
return
|
||||
}
|
||||
newValue := reflect.New(value.Type()).Elem()
|
||||
deepCopy(newValue, value)
|
||||
dst.Set(newValue)
|
||||
case reflect.Ptr:
|
||||
value := src.Elem()
|
||||
if !value.IsValid() {
|
||||
return
|
||||
}
|
||||
dst.Set(reflect.New(value.Type()))
|
||||
deepCopy(dst.Elem(), value)
|
||||
case reflect.Map:
|
||||
dst.Set(reflect.MakeMap(src.Type()))
|
||||
keys := src.MapKeys()
|
||||
for _, key := range keys {
|
||||
value := src.MapIndex(key)
|
||||
newValue := reflect.New(value.Type()).Elem()
|
||||
deepCopy(newValue, value)
|
||||
dst.SetMapIndex(key, newValue)
|
||||
}
|
||||
case reflect.Slice:
|
||||
dst.Set(reflect.MakeSlice(src.Type(), src.Len(), src.Cap()))
|
||||
for i := 0; i < src.Len(); i++ {
|
||||
deepCopy(dst.Index(i), src.Index(i))
|
||||
}
|
||||
case reflect.Struct:
|
||||
typeSrc := src.Type()
|
||||
for i := 0; i < src.NumField(); i++ {
|
||||
value := src.Field(i)
|
||||
tag := typeSrc.Field(i).Tag
|
||||
if value.CanSet() && tag.Get("deepcopy") != "-" {
|
||||
deepCopy(dst.Field(i), value)
|
||||
}
|
||||
}
|
||||
default:
|
||||
dst.Set(src)
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy(dst, src interface{}) {
|
||||
typeDst := reflect.TypeOf(dst)
|
||||
typeSrc := reflect.TypeOf(src)
|
||||
if typeDst != typeSrc {
|
||||
panic("DeepCopy: " + typeDst.String() + " != " + typeSrc.String())
|
||||
}
|
||||
if typeSrc.Kind() != reflect.Ptr {
|
||||
panic("DeepCopy: pass arguments by address")
|
||||
}
|
||||
|
||||
valueDst := reflect.ValueOf(dst).Elem()
|
||||
valueSrc := reflect.ValueOf(src).Elem()
|
||||
if !valueDst.IsValid() || !valueSrc.IsValid() {
|
||||
panic("DeepCopy: invalid arguments")
|
||||
}
|
||||
|
||||
deepCopy(valueDst, valueSrc)
|
||||
}
|
||||
|
||||
func DeepClone(v interface{}) interface{} {
|
||||
dst := reflect.New(reflect.TypeOf(v)).Elem()
|
||||
deepCopy(dst, reflect.ValueOf(v))
|
||||
return dst.Interface()
|
||||
}
|
||||
Reference in New Issue
Block a user