github.com/zly-app/zapp@v1.3.3/pkg/utils/reflect.go (about) 1 /* 2 ------------------------------------------------- 3 Author : zlyuancn 4 date: 2021/1/21 5 Description : 6 ------------------------------------------------- 7 */ 8 9 package utils 10 11 import ( 12 "reflect" 13 "unsafe" 14 ) 15 16 var Reflect = new(reflectUtil) 17 18 type reflectUtil struct{} 19 20 // 判断传入参数是否为该类型的零值 21 func (u *reflectUtil) IsZero(a interface{}) bool { 22 switch v := a.(type) { 23 case nil: 24 return true 25 case string: 26 return v == "" 27 case []byte: 28 return v == nil 29 case bool: 30 return !v 31 32 case int: 33 return v == 0 34 case int8: 35 return v == 0 36 case int16: 37 return v == 0 38 case int32: 39 return v == 0 40 case int64: 41 return v == 0 42 43 case uint: 44 return v == 0 45 case uint8: 46 return v == 0 47 case uint16: 48 return v == 0 49 case uint32: 50 return v == 0 51 case uint64: 52 return v == 0 53 54 case float32: 55 return v == 0 56 case float64: 57 return v == 0 58 59 case complex64: 60 return v == 0 61 case complex128: 62 return v == 0 63 } 64 65 rv := reflect.Indirect(reflect.ValueOf(a)) // 解包ptr 66 return u.reflectValueIsZero(rv) 67 } 68 69 func (u *reflectUtil) reflectValueIsZero(rv reflect.Value) bool { 70 switch rv.Kind() { 71 case reflect.Invalid: 72 return true 73 case reflect.Array: 74 return u.arrayIsZero(rv) 75 case reflect.String: 76 return rv.Len() == 0 77 case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.UnsafePointer, reflect.Interface, reflect.Slice: 78 return rv.IsNil() 79 case reflect.Struct: 80 return u.structIsZero(rv) 81 } 82 83 nv := reflect.New(rv.Type()).Elem().Interface() // 根据类型创建新的数据 84 85 // 尝试获取值 86 if rv.CanInterface() { 87 return rv.Interface() == nv 88 } 89 90 var p uintptr 91 if rv.CanAddr() { // 尝试获取指针 92 p = rv.UnsafeAddr() 93 } else { 94 // 强行获取指针 95 p = reflect.ValueOf(&rv).Elem().Field(1).UnsafeAddr() // &rv.ptr 96 p = *(*uintptr)(unsafe.Pointer(p)) // rv.ptr 97 } 98 99 temp := reflect.NewAt(rv.Type(), unsafe.Pointer(p)) // 根据指针创建新的数据 100 return temp.Elem().Interface() == nv 101 } 102 103 func (u *reflectUtil) structIsZero(rv reflect.Value) bool { 104 num := rv.NumField() 105 for i := 0; i < num; i++ { 106 if !u.reflectValueIsZero(rv.Field(i)) { 107 return false 108 } 109 } 110 return true 111 } 112 113 func (u *reflectUtil) arrayIsZero(rv reflect.Value) bool { 114 num := rv.Len() 115 for i := 0; i < num; i++ { 116 if !u.reflectValueIsZero(rv.Index(i)) { 117 return false 118 } 119 } 120 return true 121 }