github.com/searKing/golang/go@v1.2.117/reflect/struct.go (about) 1 // Copyright 2022 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 package reflect 6 7 import "reflect" 8 9 // FieldByNames returns the struct field with the given names. 10 // It returns the zero Value if no field was found. 11 // It panics if v's Kind is not struct. 12 func FieldByNames(v reflect.Value, names ...string) (x reflect.Value, ok bool) { 13 if !v.IsValid() || v.IsNil() { 14 return reflect.ValueOf(nil), false 15 } 16 17 if len(names) == 0 { 18 return reflect.ValueOf(nil), false 19 } 20 21 f := reflect.Indirect(v).FieldByName(names[0]) 22 if len(names) == 1 { 23 if f.IsValid() { 24 return f, true 25 } 26 return reflect.ValueOf(nil), false 27 } 28 return FieldByNames(f, names[1:]...) 29 } 30 31 // SetFieldByNames assigns x to the value v. 32 // It panics if CanSet returns false. 33 // As in Go, x's value must be assignable to type of v's son, grandson, etc 34 func SetFieldByNames(v reflect.Value, names []string, x reflect.Value) (ok bool) { 35 if !v.IsValid() || v.IsNil() { 36 return false 37 } 38 if len(names) == 0 { 39 return false 40 } 41 42 f := reflect.Indirect(v).FieldByName(names[0]) 43 if len(names) == 1 { 44 if f.IsValid() && f.Kind() == x.Kind() { 45 f.Set(x) 46 return true 47 } 48 return false 49 } 50 return SetFieldByNames(f, names[1:], x) 51 }