-
Notifications
You must be signed in to change notification settings - Fork 121
/
CopyUtil.go
68 lines (60 loc) · 1.87 KB
/
CopyUtil.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package libs
import (
"reflect"
"errors"
"encoding/json"
)
// @param dst 要被赋值的结构体,必须是指针
// @param src 数据源,必须是一个结构体(非指针)
func Copy(dst interface{}, src interface{}) (err error) {
dstValue := reflect.ValueOf(dst)
if dstValue.Kind() != reflect.Ptr {
err = errors.New("dst isn't a pointer to struct")
return
}
dstElem := dstValue.Elem()
if dstElem.Kind() != reflect.Struct {
err = errors.New("pointer doesn't point to struct")
return
}
srcValue := reflect.ValueOf(src)
srcType := reflect.TypeOf(src)
if srcType.Kind() != reflect.Struct {
err = errors.New("src isn't struct")
return
}
for i := 0; i < srcType.NumField(); i++ {
sf := srcType.Field(i)
sv := srcValue.FieldByName(sf.Name)
// make sure the value which in dst is valid and can set
if dv := dstElem.FieldByName(sf.Name); dv.IsValid() && dv.CanSet() {
dv.Set(sv)
}
}
return
}
// 结构体转为 map
// obj 必须是结构体实例,不可以是指针
// toUnderLine, 是否需要将驼峰转为 下划线
func Struct2Map(obj interface{}, toUnderline ...bool) map[string]interface{} {
t := reflect.TypeOf(obj)
v := reflect.ValueOf(obj)
var data = make(map[string]interface{})
for i := 0; i < t.NumField(); i++ {
if len(toUnderline) > 0 && toUnderline[0] {
data[TransToUnderline(t.Field(i).Name)] = v.Field(i).Interface()
} else {
data[t.Field(i).Name] = v.Field(i).Interface()
}
}
return data
}
// mapObj - map 实例
// structObj - 结构体实例指针
func Map2Struct(mapObj interface{}, structObj interface{}) error {
data, err := json.Marshal(mapObj)
if err != nil {
return err
}
return json.Unmarshal(data, structObj)
}