utils_empty.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. // Package mhayaUtils file from https://github.com/gogf/gf
  2. package mhayaUtils
  3. import "reflect"
  4. // IsEmpty checks whether given <value> empty.
  5. // It returns true if <value> is in: 0, nil, false, "", len(slice/map/chan) == 0,
  6. // or else it returns false.
  7. func IsEmpty(value interface{}) bool {
  8. if value == nil {
  9. return true
  10. }
  11. // It firstly checks the variable as common types using assertion to enhance the performance,
  12. // and then using reflection.
  13. switch val := value.(type) {
  14. case int:
  15. return val == 0
  16. case int8:
  17. return val == 0
  18. case int16:
  19. return val == 0
  20. case int32:
  21. return val == 0
  22. case int64:
  23. return val == 0
  24. case uint:
  25. return val == 0
  26. case uint8:
  27. return val == 0
  28. case uint16:
  29. return val == 0
  30. case uint32:
  31. return val == 0
  32. case uint64:
  33. return val == 0
  34. case float32:
  35. return val == 0
  36. case float64:
  37. return val == 0
  38. case bool:
  39. return !val
  40. case string:
  41. return val == ""
  42. case []byte:
  43. return len(val) == 0
  44. case []rune:
  45. return len(val) == 0
  46. case []int:
  47. return len(val) == 0
  48. case []string:
  49. return len(val) == 0
  50. case []float32:
  51. return len(val) == 0
  52. case []float64:
  53. return len(val) == 0
  54. case map[string]interface{}:
  55. return len(val) == 0
  56. default:
  57. // Finally using reflect.
  58. var rv reflect.Value
  59. if v, ok := value.(reflect.Value); ok {
  60. rv = v
  61. } else {
  62. rv = reflect.ValueOf(value)
  63. }
  64. switch rv.Kind() {
  65. case reflect.Bool:
  66. return !rv.Bool()
  67. case reflect.Int,
  68. reflect.Int8,
  69. reflect.Int16,
  70. reflect.Int32,
  71. reflect.Int64:
  72. return rv.Int() == 0
  73. case reflect.Uint,
  74. reflect.Uint8,
  75. reflect.Uint16,
  76. reflect.Uint32,
  77. reflect.Uint64,
  78. reflect.Uintptr:
  79. return rv.Uint() == 0
  80. case reflect.Float32,
  81. reflect.Float64:
  82. return rv.Float() == 0
  83. case reflect.String:
  84. return rv.Len() == 0
  85. case reflect.Struct:
  86. for i := 0; i < rv.NumField(); i++ {
  87. if !IsEmpty(rv) {
  88. return false
  89. }
  90. }
  91. return true
  92. case reflect.Chan,
  93. reflect.Map,
  94. reflect.Slice,
  95. reflect.Array:
  96. return rv.Len() == 0
  97. case reflect.Func,
  98. reflect.Ptr,
  99. reflect.Interface,
  100. reflect.UnsafePointer:
  101. if rv.IsNil() {
  102. return true
  103. }
  104. }
  105. }
  106. return false
  107. }
  108. // IsNil checks whether given <value> is nil.
  109. // Parameter <traceSource> is used for tracing to the source variable if given <value> is type
  110. // of a pinter that also points to a pointer. It returns nil if the source is nil when <traceSource>
  111. // is true.
  112. // Note that it might use reflect feature which affects performance a little bit.
  113. func IsNil(value interface{}, traceSource ...bool) bool {
  114. if value == nil {
  115. return true
  116. }
  117. var rv reflect.Value
  118. if v, ok := value.(reflect.Value); ok {
  119. rv = v
  120. } else {
  121. rv = reflect.ValueOf(value)
  122. }
  123. switch rv.Kind() {
  124. case reflect.Chan,
  125. reflect.Map,
  126. reflect.Slice,
  127. reflect.Func,
  128. reflect.Interface,
  129. reflect.UnsafePointer:
  130. return !rv.IsValid() || rv.IsNil()
  131. case reflect.Ptr:
  132. if len(traceSource) > 0 && traceSource[0] {
  133. for rv.Kind() == reflect.Ptr {
  134. rv = rv.Elem()
  135. }
  136. if !rv.IsValid() {
  137. return true
  138. }
  139. if rv.Kind() == reflect.Ptr {
  140. return rv.IsNil()
  141. }
  142. } else {
  143. return !rv.IsValid() || rv.IsNil()
  144. }
  145. }
  146. return false
  147. }