github.com/goplus/reflectx@v1.2.2/xcall.go (about)

     1  package reflectx
     2  
     3  import (
     4  	"reflect"
     5  )
     6  
     7  func FieldByIndexX(v reflect.Value, index []int) reflect.Value {
     8  	if len(index) == 1 {
     9  		return FieldX(v, index[0])
    10  	}
    11  	mustBe("reflect.Value.FieldByIndex", v, reflect.Struct)
    12  	for i, x := range index {
    13  		if i > 0 {
    14  			if v.Kind() == reflect.Ptr && v.Type().Elem().Kind() == reflect.Struct {
    15  				if v.IsNil() {
    16  					panic("reflect: indirection through nil pointer to embedded struct")
    17  				}
    18  				v = v.Elem()
    19  			}
    20  		}
    21  		v = FieldX(v, x)
    22  	}
    23  	return v
    24  }
    25  
    26  func mustBe(method string, v reflect.Value, kind reflect.Kind) {
    27  	if v.Kind() != kind {
    28  		panic(&reflect.ValueError{method, v.Kind()})
    29  	}
    30  }
    31  
    32  func FieldByNameX(v reflect.Value, name string) reflect.Value {
    33  	mustBe("reflect.Value.FieldByName", v, reflect.Struct)
    34  	if f, ok := v.Type().FieldByName(name); ok {
    35  		return FieldByIndexX(v, f.Index)
    36  	}
    37  	return reflect.Value{}
    38  }
    39  
    40  // FieldByNameFunc returns the struct field with a name
    41  // that satisfies the match function.
    42  // It panics if v's Kind is not struct.
    43  // It returns the zero Value if no field was found.
    44  func FieldByNameFuncX(v reflect.Value, match func(string) bool) reflect.Value {
    45  	if f, ok := v.Type().FieldByNameFunc(match); ok {
    46  		return FieldByIndexX(v, f.Index)
    47  	}
    48  	return reflect.Value{}
    49  }