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  }