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 }