github.com/bobyang007/helper@v1.1.3/reflecth/assert.go (about)

     1  package reflecth
     2  
     3  import "reflect"
     4  
     5  // TypeAssert perform GoLang type assertion (see language specs).
     6  // Variable x must be of interface kind (or panic/undefined behaviour happened).
     7  // Variable valid identify is assertion valid. Assertion is valid if t is of interface kind or if t implements type of x.
     8  // In Go invalid assertion causes compile time error (something like "impossible type assertion: <t> does not implement <type of x>").
     9  // Variable ok identity is assertion true. Assertion is true if x is not nil and the value stored in x is of type t.
    10  // Variable ok sets to false if valid is false, so it is valid way to check only variable ok and ignore variable valid if details of false result does not have mean.
    11  func TypeAssert(x reflect.Value, t reflect.Type) (r reflect.Value, ok bool, valid bool) {
    12  	xV := x.Elem()
    13  	valid = t.Kind() == reflect.Interface || t.Implements(x.Type())
    14  	if !valid {
    15  		return
    16  	}
    17  	if x.IsNil() {
    18  		return
    19  	}
    20  	switch t.Kind() == reflect.Interface {
    21  	case true:
    22  		ok = xV.Type().Implements(t)
    23  		if ok {
    24  			r = reflect.New(t).Elem()
    25  			r.Set(xV)
    26  		}
    27  	case false:
    28  		ok = xV.Type() == t
    29  		if ok {
    30  			r = xV
    31  		}
    32  	}
    33  	return
    34  }