1 Star 0 Fork 0

csingo / cHelper

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
Is.go 5.96 KB
一键复制 编辑 原始数据 按行查看 历史
joe 提交于 2023-12-13 18:32 . update
package cHelper
import (
"reflect"
"regexp"
"time"
"gitee.com/csingo/cReflection"
)
// iString is used for type assert api for String().
type iString interface {
String() string
}
// iInterfaces is used for type assert api for Interfaces.
type iInterfaces interface {
Interfaces() []interface{}
}
// iMapStrAny is the interface support for converting struct parameter to map.
type iMapStrAny interface {
MapStrAny() map[string]interface{}
}
type iTime interface {
Date() (year int, month time.Month, day int)
IsZero() bool
}
func IsEmpty(value interface{}) bool {
if value == nil {
return true
}
// It firstly checks the variable as common types using assertion to enhance the performance,
// and then using reflection.
switch result := value.(type) {
case int:
return result == 0
case int8:
return result == 0
case int16:
return result == 0
case int32:
return result == 0
case int64:
return result == 0
case uint:
return result == 0
case uint8:
return result == 0
case uint16:
return result == 0
case uint32:
return result == 0
case uint64:
return result == 0
case float32:
return result == 0
case float64:
return result == 0
case bool:
return result == false
case string:
return result == ""
case []byte:
return len(result) == 0
case []rune:
return len(result) == 0
case []int:
return len(result) == 0
case []string:
return len(result) == 0
case []float32:
return len(result) == 0
case []float64:
return len(result) == 0
case map[string]interface{}:
return len(result) == 0
default:
// =========================
// Common interfaces checks.
// =========================
if f, ok := value.(iTime); ok {
if f == nil {
return true
}
return f.IsZero()
}
if f, ok := value.(iString); ok {
if f == nil {
return true
}
return f.String() == ""
}
if f, ok := value.(iInterfaces); ok {
if f == nil {
return true
}
return len(f.Interfaces()) == 0
}
if f, ok := value.(iMapStrAny); ok {
if f == nil {
return true
}
return len(f.MapStrAny()) == 0
}
// Finally, using reflect.
var rv reflect.Value
if v, ok := value.(reflect.Value); ok {
rv = v
} else {
rv = reflect.ValueOf(value)
}
switch rv.Kind() {
case reflect.Bool:
return !rv.Bool()
case
reflect.Int,
reflect.Int8,
reflect.Int16,
reflect.Int32,
reflect.Int64:
return rv.Int() == 0
case
reflect.Uint,
reflect.Uint8,
reflect.Uint16,
reflect.Uint32,
reflect.Uint64,
reflect.Uintptr:
return rv.Uint() == 0
case
reflect.Float32,
reflect.Float64:
return rv.Float() == 0
case reflect.String:
return rv.Len() == 0
case reflect.Struct:
var fieldValueInterface interface{}
for i := 0; i < rv.NumField(); i++ {
fieldValueInterface, _ = cReflection.ToInterface(rv.Field(i))
if !IsEmpty(fieldValueInterface) {
return false
}
}
return true
case
reflect.Chan,
reflect.Map,
reflect.Slice,
reflect.Array:
return rv.Len() == 0
case
reflect.Func,
reflect.Ptr,
reflect.Interface,
reflect.UnsafePointer:
if rv.IsNil() {
return true
}
}
}
return false
}
func IsNil(value interface{}, traceSource ...bool) bool {
if value == nil {
return true
}
var rv reflect.Value
if v, ok := value.(reflect.Value); ok {
rv = v
} else {
rv = reflect.ValueOf(value)
}
switch rv.Kind() {
case reflect.Chan,
reflect.Map,
reflect.Slice,
reflect.Func,
reflect.Interface,
reflect.UnsafePointer:
return !rv.IsValid() || rv.IsNil()
case reflect.Ptr:
if len(traceSource) > 0 && traceSource[0] {
for rv.Kind() == reflect.Ptr {
rv = rv.Elem()
}
if !rv.IsValid() {
return true
}
if rv.Kind() == reflect.Ptr {
return rv.IsNil()
}
} else {
return !rv.IsValid() || rv.IsNil()
}
}
return false
}
// IsInt checks whether `value` is type of int.
func IsInt(value interface{}) bool {
switch value.(type) {
case int, *int, int8, *int8, int16, *int16, int32, *int32, int64, *int64:
return true
}
return false
}
// IsUint checks whether `value` is type of uint.
func IsUint(value interface{}) bool {
switch value.(type) {
case uint, *uint, uint8, *uint8, uint16, *uint16, uint32, *uint32, uint64, *uint64:
return true
}
return false
}
// IsFloat checks whether `value` is type of float.
func IsFloat(value interface{}) bool {
switch value.(type) {
case float32, *float32, float64, *float64:
return true
}
return false
}
// IsSlice checks whether `value` is type of slice.
func IsSlice(value interface{}) bool {
var (
reflectValue = reflect.ValueOf(value)
reflectKind = reflectValue.Kind()
)
for reflectKind == reflect.Ptr {
reflectValue = reflectValue.Elem()
reflectKind = reflectValue.Kind()
}
switch reflectKind {
case reflect.Slice, reflect.Array:
return true
}
return false
}
// IsMap checks whether `value` is type of map.
func IsMap(value interface{}) bool {
var (
reflectValue = reflect.ValueOf(value)
reflectKind = reflectValue.Kind()
)
for reflectKind == reflect.Ptr {
reflectValue = reflectValue.Elem()
reflectKind = reflectValue.Kind()
}
switch reflectKind {
case reflect.Map:
return true
}
return false
}
// IsStruct checks whether `value` is type of struct.
func IsStruct(value interface{}) bool {
var reflectType = reflect.TypeOf(value)
if reflectType == nil {
return false
}
var reflectKind = reflectType.Kind()
for reflectKind == reflect.Ptr {
reflectType = reflectType.Elem()
reflectKind = reflectType.Kind()
}
switch reflectKind {
case reflect.Struct:
return true
}
return false
}
// IsNumber 字符串是否为数字
func IsNumber(s string) bool {
return regexp.MustCompile(`^\d+(\.\d+)?$`).MatchString(s)
}
// IsBool 字符串是否为布尔值
func IsBool(value interface{}) bool {
switch value.(type) {
case bool, *bool:
return true
}
return false
}
// IsString 字符串是否为字符串
func IsString(value interface{}) bool {
switch value.(type) {
case string, *string:
return true
}
return false
}
Go
1
https://gitee.com/csingo/cHelper.git
git@gitee.com:csingo/cHelper.git
csingo
cHelper
cHelper
v0.4.0

搜索帮助