gutil.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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. // Package gutil provides utility functions.
  7. package gutil
  8. import (
  9. "context"
  10. "reflect"
  11. "github.com/gogf/gf/v2/errors/gerror"
  12. "github.com/gogf/gf/v2/internal/empty"
  13. "github.com/gogf/gf/v2/util/gconv"
  14. )
  15. const (
  16. dumpIndent = ` `
  17. )
  18. // Throw throws out an exception, which can be caught be TryCatch or recover.
  19. func Throw(exception interface{}) {
  20. panic(exception)
  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(ctx context.Context, try func(ctx context.Context)) (err error) {
  25. defer func() {
  26. if exception := recover(); exception != nil {
  27. if v, ok := exception.(error); ok && gerror.HasStack(v) {
  28. err = v
  29. } else {
  30. err = gerror.Newf(`%+v`, exception)
  31. }
  32. }
  33. }()
  34. try(ctx)
  35. return
  36. }
  37. // TryCatch implements try...catch... logistics using internal panic...recover.
  38. // It automatically calls function `catch` if any exception occurs and passes the exception as an error.
  39. func TryCatch(ctx context.Context, try func(ctx context.Context), catch ...func(ctx context.Context, exception error)) {
  40. defer func() {
  41. if exception := recover(); exception != nil && len(catch) > 0 {
  42. if v, ok := exception.(error); ok && gerror.HasStack(v) {
  43. catch[0](ctx, v)
  44. } else {
  45. catch[0](ctx, gerror.Newf(`%+v`, exception))
  46. }
  47. }
  48. }()
  49. try(ctx)
  50. }
  51. // IsEmpty checks given `value` empty or not.
  52. // It returns false if `value` is: integer(0), bool(false), slice/map(len=0), nil;
  53. // or else returns true.
  54. func IsEmpty(value interface{}) bool {
  55. return empty.IsEmpty(value)
  56. }
  57. // Keys retrieves and returns the keys from given map or struct.
  58. func Keys(mapOrStruct interface{}) (keysOrAttrs []string) {
  59. keysOrAttrs = make([]string, 0)
  60. if m, ok := mapOrStruct.(map[string]interface{}); ok {
  61. for k := range m {
  62. keysOrAttrs = append(keysOrAttrs, k)
  63. }
  64. return
  65. }
  66. var (
  67. reflectValue reflect.Value
  68. reflectKind reflect.Kind
  69. )
  70. if v, ok := mapOrStruct.(reflect.Value); ok {
  71. reflectValue = v
  72. } else {
  73. reflectValue = reflect.ValueOf(mapOrStruct)
  74. }
  75. reflectKind = reflectValue.Kind()
  76. for reflectKind == reflect.Ptr {
  77. if !reflectValue.IsValid() || reflectValue.IsNil() {
  78. reflectValue = reflect.New(reflectValue.Type().Elem()).Elem()
  79. reflectKind = reflectValue.Kind()
  80. } else {
  81. reflectValue = reflectValue.Elem()
  82. reflectKind = reflectValue.Kind()
  83. }
  84. }
  85. switch reflectKind {
  86. case reflect.Map:
  87. for _, k := range reflectValue.MapKeys() {
  88. keysOrAttrs = append(keysOrAttrs, gconv.String(k.Interface()))
  89. }
  90. case reflect.Struct:
  91. var (
  92. fieldType reflect.StructField
  93. reflectType = reflectValue.Type()
  94. )
  95. for i := 0; i < reflectValue.NumField(); i++ {
  96. fieldType = reflectType.Field(i)
  97. if fieldType.Anonymous {
  98. keysOrAttrs = append(keysOrAttrs, Keys(reflectValue.Field(i))...)
  99. } else {
  100. keysOrAttrs = append(keysOrAttrs, fieldType.Name)
  101. }
  102. }
  103. }
  104. return
  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. }