// Copyright 2019 getensh.com. All rights reserved. // Use of this source code is governed by getensh.com. package util import ( "errors" "reflect" ) func DeepFields(ifaceType reflect.Type) []reflect.StructField { var fields []reflect.StructField for i := 0; i < ifaceType.NumField(); i++ { v := ifaceType.Field(i) fields = append(fields, v) } return fields } // 拷贝结构体(将SrcStructPtr 拷贝到 DstStructPtr) // DstStructPtr 目标 // SrcStructPtr 来源 func StructCopy(DstStructPtr interface{}, SrcStructPtr interface{}) error { srcv := reflect.ValueOf(SrcStructPtr) dstv := reflect.ValueOf(DstStructPtr) srct := reflect.TypeOf(SrcStructPtr) dstt := reflect.TypeOf(DstStructPtr) if srct.Kind() != reflect.Ptr || dstt.Kind() != reflect.Ptr || srct.Elem().Kind() == reflect.Ptr || dstt.Elem().Kind() == reflect.Ptr { return errors.New("Fatal error:type of parameters must be Ptr of value") } if srcv.IsNil() || dstv.IsNil() { return errors.New("Fatal error:value of parameters should not be nil") } srcV := srcv.Elem() dstV := dstv.Elem() srcfields := DeepFields(reflect.ValueOf(SrcStructPtr).Elem().Type()) for _, v := range srcfields { if v.Anonymous { continue } if v.Type.Kind() == reflect.Struct || v.Type.Kind() == reflect.Slice { continue } dst := dstV.FieldByName(v.Name) src := srcV.FieldByName(v.Name) if !dst.IsValid() { continue } if src.Type() == dst.Type() && dst.CanSet() { dst.Set(src) continue } if src.Kind() == reflect.Ptr && !src.IsNil() && src.Type().Elem() == dst.Type() { dst.Set(src.Elem()) continue } if dst.Kind() == reflect.Ptr && dst.Type().Elem() == src.Type() { dst.Set(reflect.New(src.Type())) dst.Elem().Set(src) continue } } return nil }