1. 程式人生 > >兩個結構體變數的相互賦值

兩個結構體變數的相互賦值

兩個結構體變數中包含的型別相同

   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)
}

在這裡插入圖片描述