github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/zreflect/utils.go (about) 1 package zreflect 2 3 import ( 4 "reflect" 5 "strings" 6 _ "unsafe" 7 ) 8 9 const ( 10 Tag = "z" 11 ignoreTagValue = "-" 12 nameConnector = "::" 13 ) 14 15 func GetStructTag(field reflect.StructField, tags ...string) (tagValue, tagOpts string) { 16 if len(tags) > 0 { 17 for i := range tags { 18 tagValue = field.Tag.Get(tags[i]) 19 if tagValue == ignoreTagValue { 20 return "", "" 21 } 22 if t, v := checkTagValidity(tagValue); t != "" { 23 return t, v 24 } 25 } 26 } else { 27 tagValue = field.Tag.Get(Tag) 28 if tagValue == ignoreTagValue { 29 return "", "" 30 } 31 if t, v := checkTagValidity(tagValue); t != "" { 32 return t, v 33 } 34 35 tagValue = field.Tag.Get("json") 36 if tagValue == ignoreTagValue { 37 return "", "" 38 } 39 if t, v := checkTagValidity(tagValue); t != "" { 40 return t, v 41 } 42 } 43 44 return field.Name, "" 45 } 46 47 func Nonzero(v reflect.Value) bool { 48 switch v.Kind() { 49 case reflect.Bool: 50 return v.Bool() 51 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 52 return v.Int() != 0 53 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 54 return v.Uint() != 0 55 case reflect.Float32, reflect.Float64: 56 return v.Float() != 0 57 case reflect.Complex64, reflect.Complex128: 58 return v.Complex() != complex(0, 0) 59 case reflect.String: 60 return v.String() != "" 61 case reflect.Struct: 62 for i := 0; i < v.NumField(); i++ { 63 if Nonzero(reflect.Indirect(v.Field(i))) { 64 return true 65 } 66 } 67 return false 68 case reflect.Array: 69 for i := 0; i < v.Len(); i++ { 70 if Nonzero(v.Index(i)) { 71 return true 72 } 73 } 74 return false 75 case reflect.Map, reflect.Interface, reflect.Slice, reflect.Ptr, reflect.Chan, reflect.Func: 76 return !v.IsNil() 77 case reflect.UnsafePointer: 78 return v.Pointer() != 0 79 } 80 return true 81 } 82 83 func CanExpand(t reflect.Type) bool { 84 switch t.Kind() { 85 case reflect.Map, reflect.Struct, 86 reflect.Interface, reflect.Array, reflect.Slice, 87 reflect.Ptr: 88 return true 89 } 90 return false 91 } 92 93 func CanInline(t reflect.Type) bool { 94 switch t.Kind() { 95 case reflect.Map: 96 return !CanExpand(t.Elem()) 97 case reflect.Struct: 98 for i := 0; i < t.NumField(); i++ { 99 if CanExpand(t.Field(i).Type) { 100 return false 101 } 102 } 103 return true 104 case reflect.Interface: 105 return false 106 case reflect.Array, reflect.Slice: 107 return !CanExpand(t.Elem()) 108 case reflect.Ptr: 109 return false 110 case reflect.Chan, reflect.Func, reflect.UnsafePointer: 111 return false 112 } 113 return true 114 } 115 116 func IsLabel(t reflect.Type) bool { 117 switch t.Kind() { 118 case reflect.Interface, reflect.Struct: 119 return true 120 } 121 return false 122 } 123 124 func checkTagValidity(tagValue string) (tag, tagOpts string) { 125 if tagValue == "" { 126 return "", "" 127 } 128 valueSplit := strings.SplitN(tagValue, ",", 2) 129 if len(valueSplit) < 2 { 130 return valueSplit[0], "" 131 } 132 return valueSplit[0], valueSplit[1] 133 } 134 135 //go:linkname ifaceIndir reflect.ifaceIndir 136 //go:noescape 137 func ifaceIndir(Type) bool 138 139 func GetAbbrKind(val reflect.Value) reflect.Kind { 140 kind := val.Kind() 141 switch { 142 case kind >= reflect.Int && kind <= reflect.Int64: 143 return reflect.Int 144 case kind >= reflect.Uint && kind <= reflect.Uint64: 145 return reflect.Uint 146 case kind >= reflect.Float32 && kind <= reflect.Float64: 147 return reflect.Float64 148 default: 149 return kind 150 } 151 }