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  }