-
Notifications
You must be signed in to change notification settings - Fork 0
/
reflect_type.go
133 lines (121 loc) · 3.48 KB
/
reflect_type.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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package util
import (
"reflect"
)
// InitPointer with value
func InitPointer(src reflect.Type) (dst reflect.Value) {
if src.Kind() == reflect.Ptr {
data := InitPointer(src.Elem())
dst = reflect.Indirect(reflect.New(src))
if dst.CanSet() {
if data.CanAddr() {
dst.Set(data.Addr())
}
}
} else {
dst = InitWithZeroValue(src)
}
return
}
// InitWithZeroValue init type with default value
func InitWithZeroValue(src reflect.Type) (dst reflect.Value) {
dst = reflect.Indirect(reflect.New(src))
switch dst.Kind() {
case reflect.Invalid:
case reflect.Bool:
dst.SetBool(false)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
dst.SetInt(0)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
dst.SetUint(0)
case reflect.Uintptr:
case reflect.Float32, reflect.Float64:
dst.SetFloat(0)
case reflect.Complex64, reflect.Complex128:
dst.SetComplex(complex(0, 0))
case reflect.Array:
dst.Set(reflect.MakeSlice(dst.Type(), 0, 0))
case reflect.Chan:
dst.Set(reflect.MakeChan(dst.Type(), 0))
case reflect.Func:
dst.Set(reflect.MakeFunc(dst.Type(), func(args []reflect.Value) (results []reflect.Value) {
return
}))
case reflect.Interface:
case reflect.Map:
dst.Set(reflect.MakeMap(dst.Type()))
case reflect.Ptr:
case reflect.Slice:
dst.Set(reflect.MakeSlice(dst.Type(), 0, 0))
case reflect.String:
dst.SetString("")
case reflect.Struct:
numField := dst.NumField()
for i := 0; i < numField; i++ {
fieldValue := dst.Field(i)
fieldValue.Set(InitWithZeroValue(fieldValue.Type()))
}
case reflect.UnsafePointer:
}
return
}
// InitWithZeroValueExcludePtr init type with default value
// if v.Kind() == reflect.Ptr, will init by zero value which point to
// example var a *int, a is not nil, *a = 0
func InitWithZeroValueExcludePtr(src reflect.Type) (dst reflect.Value) {
dst = reflect.Indirect(reflect.New(src))
switch dst.Kind() {
case reflect.Invalid:
case reflect.Bool:
dst.SetBool(false)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
dst.SetInt(0)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
dst.SetUint(0)
case reflect.Uintptr:
case reflect.Float32, reflect.Float64:
dst.SetFloat(0)
case reflect.Complex64, reflect.Complex128:
dst.SetComplex(complex(0, 0))
case reflect.Array:
dst.Set(reflect.MakeSlice(dst.Type(), 0, 0))
case reflect.Chan:
dst.Set(reflect.MakeChan(dst.Type(), 0))
case reflect.Func:
dst.Set(reflect.MakeFunc(dst.Type(), func(args []reflect.Value) (results []reflect.Value) {
return
}))
case reflect.Interface:
case reflect.Map:
dst.Set(reflect.MakeMap(dst.Type()))
case reflect.Ptr:
data := InitWithZeroValueExcludePtr(src.Elem())
dst = reflect.Indirect(reflect.New(src))
if dst.CanSet() {
if data.CanAddr() {
dst.Set(data.Addr())
}
}
case reflect.Slice:
dst.Set(reflect.MakeSlice(dst.Type(), 0, 0))
case reflect.String:
dst.SetString("")
case reflect.Struct:
numField := dst.NumField()
for i := 0; i < numField; i++ {
fieldValue := dst.Field(i)
fieldValue.Set(InitWithZeroValueExcludePtr(fieldValue.Type()))
}
case reflect.UnsafePointer:
}
return
}
// IsExportedOrBuiltinType Is this type exported or a builtin?
func IsExportedOrBuiltinType(t reflect.Type) bool {
for t.Kind() == reflect.Ptr {
t = t.Elem()
}
// PkgPath will be non-empty even for an exported type,
// so we need to check the type name as well.
return IsExported(t.Name()) || t.PkgPath() == ""
}