func TestCopy(t *testing.T) { var str = "demoA" a := &A{ Name: &str, Id: 1, Uid: 320, Price: 12.3, Info: "info...", Sex: true, } b := &B{Name: "demo"} logger.StdDebug("before copy :%v:%v:%v", b.Mid, b.Name, b.Sex) gocopy.Copy(a, b) logger.StdDebug("after copy :%v:%v:%v", b.Mid, b.Name, b.Sex) }
func Copy(a, b interface{}) { defer func() { if err := recover(); err != nil { logger.StdDebug("%v", err) } }() rta := reflect.TypeOf(a).Elem() if rta.Kind() != reflect.Struct { panic("request struct accept " + rta.Kind().String()) } rtb := reflect.TypeOf(b).Elem() if rtb.Kind() != reflect.Struct { panic("request struct accept " + rta.Kind().String()) } rva := reflect.ValueOf(a).Elem() rvb := reflect.ValueOf(b).Elem() for i := 0; i < rta.NumField(); i++ { v := rva.Field(i) switch rva.Field(i).Kind() { case reflect.String: ma[rta.Field(i).Name] = rva.Field(i) case reflect.PtrTo(reflect.TypeOf("")).Kind(): ma[rta.Field(i).Name] = rva.Field(i) case reflect.Int8, reflect.Int16, reflect.Int, reflect.Int32, reflect.Int64: ma[rta.Field(i).Name] = rva.Field(i) case reflect.Uint8, reflect.Uint16, reflect.Uint, reflect.Uint32, reflect.Uint64: ma[rta.Field(i).Name] = rva.Field(i) case reflect.Float32, reflect.Float64: ma[rta.Field(i).Name] = rva.Field(i) case reflect.Bool: ma[rta.Field(i).Name] = rva.Field(i) default: logger.StdDebug("type v %v not catch", v.Type()) } } var nb = map[string]string{} for i := 0; i < rtb.NumField(); i++ { if rtb.Field(i).Tag.Get("cp") == "" { mb[rtb.Field(i).Name] = rvb.Field(i) } else { nb[rtb.Field(i).Name] = rtb.Field(i).Tag.Get("cp") mb[rtb.Field(i).Name] = rvb.Field(i) } } for k, _ := range mb { old := k if nameB, ok := nb[k]; ok { k = nameB } if _, ok := ma[k]; ok { if _, ok = mb[old]; ok { if ma[k].Kind() == reflect.Ptr { if ma[k].Elem().Kind() == reflect.String { mb[old].SetString(ma[k].Elem().String()) } if ma[k].Elem().Kind() == reflect.Bool { mb[old].SetBool(ma[k].Elem().Bool()) } if ma[k].Elem().Kind() == reflect.Int { mb[old].SetInt(ma[k].Elem().Int()) } } else { if ma[k].Kind() == reflect.String { mb[old].SetString(ma[k].String()) } if ma[k].Kind() == reflect.Bool { mb[old].SetBool(true) } if ma[k].Kind() == reflect.Int64 { mb[old].SetInt(ma[k].Int()) } } } } } }