github.com/gogf/gf@v1.16.9/util/gutil/gutil.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 // Package gutil provides utility functions. 8 package gutil 9 10 import ( 11 "fmt" 12 "github.com/gogf/gf/internal/empty" 13 "github.com/gogf/gf/util/gconv" 14 "reflect" 15 ) 16 17 // Throw throws out an exception, which can be caught be TryCatch or recover. 18 func Throw(exception interface{}) { 19 panic(exception) 20 } 21 22 // Try implements try... logistics using internal panic...recover. 23 // It returns error if any exception occurs, or else it returns nil. 24 func Try(try func()) (err error) { 25 defer func() { 26 if e := recover(); e != nil { 27 err = fmt.Errorf(`%v`, e) 28 } 29 }() 30 try() 31 return 32 } 33 34 // TryCatch implements try...catch... logistics using internal panic...recover. 35 // It automatically calls function `catch` if any exception occurs ans passes the exception as an error. 36 func TryCatch(try func(), catch ...func(exception error)) { 37 defer func() { 38 if exception := recover(); exception != nil && len(catch) > 0 { 39 if err, ok := exception.(error); ok { 40 catch[0](err) 41 } else { 42 catch[0](fmt.Errorf(`%v`, exception)) 43 } 44 } 45 }() 46 try() 47 } 48 49 // IsEmpty checks given `value` empty or not. 50 // It returns false if `value` is: integer(0), bool(false), slice/map(len=0), nil; 51 // or else returns true. 52 func IsEmpty(value interface{}) bool { 53 return empty.IsEmpty(value) 54 } 55 56 // Keys retrieves and returns the keys from given map or struct. 57 func Keys(mapOrStruct interface{}) (keysOrAttrs []string) { 58 keysOrAttrs = make([]string, 0) 59 if m, ok := mapOrStruct.(map[string]interface{}); ok { 60 for k, _ := range m { 61 keysOrAttrs = append(keysOrAttrs, k) 62 } 63 return 64 } 65 var ( 66 reflectValue reflect.Value 67 reflectKind reflect.Kind 68 ) 69 if v, ok := mapOrStruct.(reflect.Value); ok { 70 reflectValue = v 71 } else { 72 reflectValue = reflect.ValueOf(mapOrStruct) 73 } 74 reflectKind = reflectValue.Kind() 75 for reflectKind == reflect.Ptr { 76 if !reflectValue.IsValid() || reflectValue.IsNil() { 77 reflectValue = reflect.New(reflectValue.Type().Elem()).Elem() 78 reflectKind = reflectValue.Kind() 79 } else { 80 reflectValue = reflectValue.Elem() 81 reflectKind = reflectValue.Kind() 82 } 83 } 84 switch reflectKind { 85 case reflect.Map: 86 for _, k := range reflectValue.MapKeys() { 87 keysOrAttrs = append(keysOrAttrs, gconv.String(k.Interface())) 88 } 89 case reflect.Struct: 90 var ( 91 fieldType reflect.StructField 92 reflectType = reflectValue.Type() 93 ) 94 for i := 0; i < reflectValue.NumField(); i++ { 95 fieldType = reflectType.Field(i) 96 if fieldType.Anonymous { 97 keysOrAttrs = append(keysOrAttrs, Keys(reflectValue.Field(i))...) 98 } else { 99 keysOrAttrs = append(keysOrAttrs, fieldType.Name) 100 } 101 } 102 } 103 return 104 } 105 106 // Values retrieves and returns the values from given map or struct. 107 func Values(mapOrStruct interface{}) (values []interface{}) { 108 values = make([]interface{}, 0) 109 if m, ok := mapOrStruct.(map[string]interface{}); ok { 110 for _, v := range m { 111 values = append(values, v) 112 } 113 return 114 } 115 var ( 116 reflectValue reflect.Value 117 reflectKind reflect.Kind 118 ) 119 if v, ok := mapOrStruct.(reflect.Value); ok { 120 reflectValue = v 121 } else { 122 reflectValue = reflect.ValueOf(mapOrStruct) 123 } 124 reflectKind = reflectValue.Kind() 125 for reflectKind == reflect.Ptr { 126 reflectValue = reflectValue.Elem() 127 reflectKind = reflectValue.Kind() 128 } 129 switch reflectKind { 130 case reflect.Map: 131 for _, k := range reflectValue.MapKeys() { 132 values = append(values, reflectValue.MapIndex(k).Interface()) 133 } 134 case reflect.Struct: 135 var ( 136 fieldType reflect.StructField 137 reflectType = reflectValue.Type() 138 ) 139 for i := 0; i < reflectValue.NumField(); i++ { 140 fieldType = reflectType.Field(i) 141 if fieldType.Anonymous { 142 values = append(values, Values(reflectValue.Field(i))...) 143 } else { 144 values = append(values, reflectValue.Field(i).Interface()) 145 } 146 } 147 } 148 return 149 }