兩個結構體變數的相互賦值
阿新 • • 發佈:2019-01-05
兩個結構體變數中包含的型別相同
func DeepFields(ifaceType reflect.Type) []reflect.StructField { var fields []reflect.StructField for i := 0; i < ifaceType.NumField(); i++ { v := ifaceType.Field(i) if v.Anonymous && v.Type.Kind() == reflect.Struct { fields = append(fields, DeepFields(v.Type)...) } else { fields = append(fields, v) } } return fields } func StructCopy(DstStructPtr interface{}, SrcStructPtr interface{}) { 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 { panic("Fatal error:type of parameters must be Ptr of value") } if srcv.IsNil() || dstv.IsNil() { panic("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 } 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 } type Src struct { Name string ID string } type Dst struct { Name string ID string } //測試如下: src := &Src{"wilson", "007"} var dst Dst StructCopy(&dst, src) fmt.Println(dst)
下面開始討論兩個結構體變數的型別相同,即同一種類型的結構體賦值
package main import ( "fmt" "encoding/json" ) type Foo1 struct { id int m map[int]string } func main() { //funcName() //var f1 Foo1 f1 := &Foo1{id: 3, m: map[int]string{1: "hello", 2: "hello1"}} var f2 Foo1 f2.m = make(map[int]string) for key, value := range f1.m { //f2.m[key]=value f2.m[key] = value } f2.m[1]="world" fmt.Println(&f2) fmt.Println(f1) }