empty.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. // Copyright 2019 gf Author(https://github.com/gogf/gf). 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 empty provides functions for checking empty variables.
  7. package empty
  8. import (
  9. "reflect"
  10. )
  11. // apiString is used for type assert api for String().
  12. type apiString interface {
  13. String() string
  14. }
  15. // apiInterfaces is used for type assert api for Interfaces.
  16. type apiInterfaces interface {
  17. Interfaces() []interface{}
  18. }
  19. // apiMapStrAny is the interface support for converting struct parameter to map.
  20. type apiMapStrAny interface {
  21. MapStrAny() map[string]interface{}
  22. }
  23. // IsEmpty checks whether given <value> empty.
  24. // It returns true if <value> is in: 0, nil, false, "", len(slice/map/chan) == 0,
  25. // or else it returns false.
  26. func IsEmpty(value interface{}) bool {
  27. if value == nil {
  28. return true
  29. }
  30. // It firstly checks the variable as common types using assertion to enhance the performance,
  31. // and then using reflection.
  32. switch value := value.(type) {
  33. case int:
  34. return value == 0
  35. case int8:
  36. return value == 0
  37. case int16:
  38. return value == 0
  39. case int32:
  40. return value == 0
  41. case int64:
  42. return value == 0
  43. case uint:
  44. return value == 0
  45. case uint8:
  46. return value == 0
  47. case uint16:
  48. return value == 0
  49. case uint32:
  50. return value == 0
  51. case uint64:
  52. return value == 0
  53. case float32:
  54. return value == 0
  55. case float64:
  56. return value == 0
  57. case bool:
  58. return value == false
  59. case string:
  60. return value == ""
  61. case []byte:
  62. return len(value) == 0
  63. case []rune:
  64. return len(value) == 0
  65. case []int:
  66. return len(value) == 0
  67. case []string:
  68. return len(value) == 0
  69. case []float32:
  70. return len(value) == 0
  71. case []float64:
  72. return len(value) == 0
  73. case map[string]interface{}:
  74. return len(value) == 0
  75. default:
  76. // Common interfaces checks.
  77. if f, ok := value.(apiString); ok {
  78. if f == nil {
  79. return true
  80. }
  81. return f.String() == ""
  82. }
  83. if f, ok := value.(apiInterfaces); ok {
  84. if f == nil {
  85. return true
  86. }
  87. return len(f.Interfaces()) == 0
  88. }
  89. if f, ok := value.(apiMapStrAny); ok {
  90. if f == nil {
  91. return true
  92. }
  93. return len(f.MapStrAny()) == 0
  94. }
  95. // Finally using reflect.
  96. var rv reflect.Value
  97. if v, ok := value.(reflect.Value); ok {
  98. rv = v
  99. } else {
  100. rv = reflect.ValueOf(value)
  101. }
  102. switch rv.Kind() {
  103. case reflect.Bool:
  104. return !rv.Bool()
  105. case reflect.Int,
  106. reflect.Int8,
  107. reflect.Int16,
  108. reflect.Int32,
  109. reflect.Int64:
  110. return rv.Int() == 0
  111. case reflect.Uint,
  112. reflect.Uint8,
  113. reflect.Uint16,
  114. reflect.Uint32,
  115. reflect.Uint64,
  116. reflect.Uintptr:
  117. return rv.Uint() == 0
  118. case reflect.Float32,
  119. reflect.Float64:
  120. return rv.Float() == 0
  121. case reflect.String:
  122. return rv.Len() == 0
  123. case reflect.Struct:
  124. for i := 0; i < rv.NumField(); i++ {
  125. if !IsEmpty(rv) {
  126. return false
  127. }
  128. }
  129. return true
  130. case reflect.Chan,
  131. reflect.Map,
  132. reflect.Slice,
  133. reflect.Array:
  134. return rv.Len() == 0
  135. case reflect.Func,
  136. reflect.Ptr,
  137. reflect.Interface,
  138. reflect.UnsafePointer:
  139. if rv.IsNil() {
  140. return true
  141. }
  142. }
  143. }
  144. return false
  145. }
  146. // IsNil checks whether given <value> is nil.
  147. // Note that it might use reflect feature which affects performance a little bit.
  148. func IsNil(value interface{}) bool {
  149. if value == nil {
  150. return true
  151. }
  152. var rv reflect.Value
  153. if v, ok := value.(reflect.Value); ok {
  154. rv = v
  155. } else {
  156. rv = reflect.ValueOf(value)
  157. }
  158. switch rv.Kind() {
  159. case reflect.Chan,
  160. reflect.Map,
  161. reflect.Slice,
  162. reflect.Func,
  163. reflect.Ptr,
  164. reflect.Interface,
  165. reflect.UnsafePointer:
  166. return rv.IsNil()
  167. }
  168. return false
  169. }