empty.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. // Copyright GoFrame gf 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 empty provides functions for checking empty/nil variables.
  7. package empty
  8. import (
  9. "reflect"
  10. "time"
  11. )
  12. // apiString is used for type assert api for String().
  13. type apiString interface {
  14. String() string
  15. }
  16. // apiInterfaces is used for type assert api for Interfaces.
  17. type apiInterfaces interface {
  18. Interfaces() []interface{}
  19. }
  20. // apiMapStrAny is the interface support for converting struct parameter to map.
  21. type apiMapStrAny interface {
  22. MapStrAny() map[string]interface{}
  23. }
  24. type apiTime interface {
  25. Date() (year int, month time.Month, day int)
  26. IsZero() bool
  27. }
  28. // IsEmpty checks whether given `value` empty.
  29. // It returns true if `value` is in: 0, nil, false, "", len(slice/map/chan) == 0,
  30. // or else it returns false.
  31. func IsEmpty(value interface{}) bool {
  32. if value == nil {
  33. return true
  34. }
  35. // It firstly checks the variable as common types using assertion to enhance the performance,
  36. // and then using reflection.
  37. switch value := value.(type) {
  38. case int:
  39. return value == 0
  40. case int8:
  41. return value == 0
  42. case int16:
  43. return value == 0
  44. case int32:
  45. return value == 0
  46. case int64:
  47. return value == 0
  48. case uint:
  49. return value == 0
  50. case uint8:
  51. return value == 0
  52. case uint16:
  53. return value == 0
  54. case uint32:
  55. return value == 0
  56. case uint64:
  57. return value == 0
  58. case float32:
  59. return value == 0
  60. case float64:
  61. return value == 0
  62. case bool:
  63. return value == false
  64. case string:
  65. return value == ""
  66. case []byte:
  67. return len(value) == 0
  68. case []rune:
  69. return len(value) == 0
  70. case []int:
  71. return len(value) == 0
  72. case []string:
  73. return len(value) == 0
  74. case []float32:
  75. return len(value) == 0
  76. case []float64:
  77. return len(value) == 0
  78. case map[string]interface{}:
  79. return len(value) == 0
  80. default:
  81. // =========================
  82. // Common interfaces checks.
  83. // =========================
  84. if f, ok := value.(apiTime); ok {
  85. if f == nil {
  86. return true
  87. }
  88. return f.IsZero()
  89. }
  90. if f, ok := value.(apiString); ok {
  91. if f == nil {
  92. return true
  93. }
  94. return f.String() == ""
  95. }
  96. if f, ok := value.(apiInterfaces); ok {
  97. if f == nil {
  98. return true
  99. }
  100. return len(f.Interfaces()) == 0
  101. }
  102. if f, ok := value.(apiMapStrAny); ok {
  103. if f == nil {
  104. return true
  105. }
  106. return len(f.MapStrAny()) == 0
  107. }
  108. // Finally using reflect.
  109. var rv reflect.Value
  110. if v, ok := value.(reflect.Value); ok {
  111. rv = v
  112. } else {
  113. rv = reflect.ValueOf(value)
  114. }
  115. switch rv.Kind() {
  116. case reflect.Bool:
  117. return !rv.Bool()
  118. case reflect.Int,
  119. reflect.Int8,
  120. reflect.Int16,
  121. reflect.Int32,
  122. reflect.Int64:
  123. return rv.Int() == 0
  124. case reflect.Uint,
  125. reflect.Uint8,
  126. reflect.Uint16,
  127. reflect.Uint32,
  128. reflect.Uint64,
  129. reflect.Uintptr:
  130. return rv.Uint() == 0
  131. case reflect.Float32,
  132. reflect.Float64:
  133. return rv.Float() == 0
  134. case reflect.String:
  135. return rv.Len() == 0
  136. case reflect.Struct:
  137. for i := 0; i < rv.NumField(); i++ {
  138. if !IsEmpty(rv) {
  139. return false
  140. }
  141. }
  142. return true
  143. case reflect.Chan,
  144. reflect.Map,
  145. reflect.Slice,
  146. reflect.Array:
  147. return rv.Len() == 0
  148. case reflect.Func,
  149. reflect.Ptr,
  150. reflect.Interface,
  151. reflect.UnsafePointer:
  152. if rv.IsNil() {
  153. return true
  154. }
  155. }
  156. }
  157. return false
  158. }
  159. // IsEmptyLength checks whether given `value` is empty length.
  160. // It returns true if `value` is in: nil, "", len(slice/map/chan) == 0,
  161. // or else it returns false.
  162. //func IsEmptyLength(value interface{}) bool {
  163. // if value == nil {
  164. // return true
  165. // }
  166. // // It firstly checks the variable as common types using assertion to enhance the performance,
  167. // // and then using reflection.
  168. // switch value := value.(type) {
  169. // case
  170. // int,
  171. // int8,
  172. // int16,
  173. // int32,
  174. // int64,
  175. // uint,
  176. // uint8,
  177. // uint16,
  178. // uint32,
  179. // uint64,
  180. // float32,
  181. // float64,
  182. // bool:
  183. // return false
  184. // case string:
  185. // return value == ""
  186. // case []byte:
  187. // return len(value) == 0
  188. // case []rune:
  189. // return len(value) == 0
  190. // case []int:
  191. // return len(value) == 0
  192. // case []string:
  193. // return len(value) == 0
  194. // case []float32:
  195. // return len(value) == 0
  196. // case []float64:
  197. // return len(value) == 0
  198. // case map[string]interface{}:
  199. // return len(value) == 0
  200. // default:
  201. // // =========================
  202. // // Common interfaces checks.
  203. // // =========================
  204. // if f, ok := value.(apiTime); ok {
  205. // if f == nil {
  206. // return true
  207. // }
  208. // return f.IsZero()
  209. // }
  210. // if f, ok := value.(apiString); ok {
  211. // if f == nil {
  212. // return true
  213. // }
  214. // return f.String() == ""
  215. // }
  216. // if f, ok := value.(apiInterfaces); ok {
  217. // if f == nil {
  218. // return true
  219. // }
  220. // return len(f.Interfaces()) == 0
  221. // }
  222. // if f, ok := value.(apiMapStrAny); ok {
  223. // if f == nil {
  224. // return true
  225. // }
  226. // return len(f.MapStrAny()) == 0
  227. // }
  228. // // Finally using reflect.
  229. // var rv reflect.Value
  230. // if v, ok := value.(reflect.Value); ok {
  231. // rv = v
  232. // } else {
  233. // rv = reflect.ValueOf(value)
  234. // }
  235. //
  236. // switch rv.Kind() {
  237. // case
  238. // reflect.Int,
  239. // reflect.Int8,
  240. // reflect.Int16,
  241. // reflect.Int32,
  242. // reflect.Int64,
  243. // reflect.Uint,
  244. // reflect.Uint8,
  245. // reflect.Uint16,
  246. // reflect.Uint32,
  247. // reflect.Uint64,
  248. // reflect.Uintptr,
  249. // reflect.Float32,
  250. // reflect.Float64,
  251. // reflect.Bool:
  252. // return false
  253. // case reflect.String:
  254. // return rv.Len() == 0
  255. // case reflect.Struct:
  256. // for i := 0; i < rv.NumField(); i++ {
  257. // if !IsEmpty(rv) {
  258. // return false
  259. // }
  260. // }
  261. // return true
  262. // case reflect.Chan,
  263. // reflect.Map,
  264. // reflect.Slice,
  265. // reflect.Array:
  266. // return rv.Len() == 0
  267. // case reflect.Func,
  268. // reflect.Ptr,
  269. // reflect.Interface,
  270. // reflect.UnsafePointer:
  271. // if rv.IsNil() {
  272. // return true
  273. // }
  274. // }
  275. // }
  276. // return false
  277. //}
  278. // IsNil checks whether given `value` is nil.
  279. // Parameter `traceSource` is used for tracing to the source variable if given `value` is type of pinter
  280. // that also points to a pointer. It returns nil if the source is nil when `traceSource` is true.
  281. // Note that it might use reflect feature which affects performance a little.
  282. func IsNil(value interface{}, traceSource ...bool) bool {
  283. if value == nil {
  284. return true
  285. }
  286. var rv reflect.Value
  287. if v, ok := value.(reflect.Value); ok {
  288. rv = v
  289. } else {
  290. rv = reflect.ValueOf(value)
  291. }
  292. switch rv.Kind() {
  293. case reflect.Chan,
  294. reflect.Map,
  295. reflect.Slice,
  296. reflect.Func,
  297. reflect.Interface,
  298. reflect.UnsafePointer:
  299. return !rv.IsValid() || rv.IsNil()
  300. case reflect.Ptr:
  301. if len(traceSource) > 0 && traceSource[0] {
  302. for rv.Kind() == reflect.Ptr {
  303. rv = rv.Elem()
  304. }
  305. if !rv.IsValid() {
  306. return true
  307. }
  308. if rv.Kind() == reflect.Ptr {
  309. return rv.IsNil()
  310. }
  311. } else {
  312. return !rv.IsValid() || rv.IsNil()
  313. }
  314. }
  315. return false
  316. }