forked from shutterstock/go-stockutil
/
reflect.go
92 lines (76 loc) · 1.56 KB
/
reflect.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
package utils
import (
"reflect"
)
var SliceTypes = []reflect.Kind{
reflect.Slice,
reflect.Array,
}
var CompoundTypes = []reflect.Kind{
reflect.Invalid,
reflect.Complex64,
reflect.Complex128,
reflect.Array,
reflect.Chan,
reflect.Func,
reflect.Interface,
reflect.Map,
reflect.Ptr,
reflect.Slice,
reflect.Struct,
}
func ResolveValue(in interface{}) interface{} {
var inV reflect.Value
if vV, ok := in.(reflect.Value); ok {
inV = vV
} else {
inV = reflect.ValueOf(in)
}
if inV.IsValid() {
if inT := inV.Type(); inT == nil {
return nil
}
switch inV.Kind() {
case reflect.Ptr, reflect.Interface:
return ResolveValue(inV.Elem())
}
in = inV.Interface()
}
return in
}
// Dectect whether the concrete underlying value of the given input is one or more
// Kinds of value.
func IsKind(in interface{}, kinds ...reflect.Kind) bool {
var inT reflect.Type
if v, ok := in.(reflect.Value); ok && v.IsValid() {
inT = v.Type()
} else if v, ok := in.(reflect.Type); ok {
inT = v
} else {
in = ResolveValue(in)
inT = reflect.TypeOf(in)
}
if inT == nil {
return false
}
for _, k := range kinds {
if inT.Kind() == k {
return true
}
}
return false
}
// Returns whether the given value represents the underlying type's zero value
func IsZero(value interface{}) bool {
if value == nil {
return true
} else if valueV, ok := value.(reflect.Value); ok && valueV.IsValid() {
if valueV.CanInterface() {
value = valueV.Interface()
}
}
return reflect.DeepEqual(
value,
reflect.Zero(reflect.TypeOf(value)).Interface(),
)
}