github.com/searKing/golang/go@v1.2.74/util/object/zero_go1.12.go (about) 1 // Copyright 2020 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build !go1.13 6 7 package object 8 9 import ( 10 "math" 11 "reflect" 12 ) 13 14 // IsZero reports whether v is the zero value for its type. 15 // It panics if the argument is invalid. 16 // it's borrowed from https://github.com/golang/go/blob/master/src/reflect/value.go from go1.13 17 func IsZero(obj interface{}) bool { 18 var v reflect.Value 19 20 if vv, ok := obj.(reflect.Value); ok { 21 v = vv 22 } else { 23 v = reflect.ValueOf(obj) 24 } 25 26 switch v.Kind() { 27 case reflect.Bool: 28 return !v.Bool() 29 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 30 return v.Int() == 0 31 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 32 return v.Uint() == 0 33 case reflect.Float32, reflect.Float64: 34 return math.Float64bits(v.Float()) == 0 35 case reflect.Complex64, reflect.Complex128: 36 c := v.Complex() 37 return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0 38 case reflect.Array: 39 for i := 0; i < v.Len(); i++ { 40 if !IsZero(v.Index(i)) { 41 return false 42 } 43 } 44 return true 45 case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer: 46 return v.IsNil() 47 case reflect.String: 48 return v.Len() == 0 49 case reflect.Struct: 50 for i := 0; i < v.NumField(); i++ { 51 if !IsZero(v.Field(i)) { 52 return false 53 } 54 } 55 return true 56 default: 57 // This should never happens, but will act as a safeguard for 58 // later, as a default value doesn't makes sense here. 59 panic(&reflect.ValueError{Method: "reflect.Value.IsZero", Kind: v.Kind()}) 60 } 61 } 62 63 // Zero returns a Value representing the zero value for the specified type. 64 // The result is different from the zero value of the Value struct, 65 // which represents no value at all. 66 // For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0. 67 // The returned value is neither addressable nor settable. 68 func Zero(obj interface{}) interface{} { 69 var v reflect.Value 70 if vv, ok := obj.(reflect.Value); ok { 71 v = vv 72 } else { 73 v = reflect.ValueOf(obj) 74 } 75 return reflect.Zero(v.Type()).Interface() 76 }