github.com/wfusion/gofusion@v1.1.14/common/utils/inspect/field_go118.go (about)

     1  //go:build go1.18
     2  // +build go1.18
     3  
     4  // Inspired by github.com/chenzhuoyu/go-inspect
     5  
     6  package inspect
     7  
     8  import (
     9  	"reflect"
    10  	"unsafe"
    11  )
    12  
    13  // FieldByName locates a field with name.
    14  func FieldByName(v reflect.Value, name string) (Field, bool) {
    15  	if fv, ok := v.Type().FieldByName(name); !ok {
    16  		return Field{}, false
    17  	} else {
    18  		return newField(v, fv), true
    19  	}
    20  }
    21  
    22  // FieldAt locates a field with index.
    23  func FieldAt(v reflect.Value, idx int) (Field, bool) {
    24  	if idx < 0 || idx >= v.NumField() {
    25  		return Field{}, false
    26  	} else {
    27  		return newField(v, v.Type().Field(idx)), true
    28  	}
    29  }
    30  
    31  func SetField[T any](obj any, fieldName string, val T) {
    32  	mustOk(FieldByName(derefValue(reflect.ValueOf(obj)), fieldName)).Set(reflect.ValueOf(val))
    33  }
    34  
    35  func GetField[T any](obj any, fieldName string) (r T) {
    36  	r, _ = mustOk(FieldByName(derefValue(reflect.ValueOf(obj)), fieldName)).Get().Interface().(T)
    37  	return
    38  }
    39  
    40  // deprecated
    41  func setField[T any](obj any, fieldName string, val T) {
    42  	v := reflect.ValueOf(obj)
    43  	t := reflect.Indirect(v).Type()
    44  	*(*T)(unsafe.Pointer(v.Pointer() + mustOk(t.FieldByName(fieldName)).Offset)) = val
    45  }
    46  
    47  // deprecated
    48  func getField[T any](obj any, fieldName string) (r T) {
    49  	v := reflect.Indirect(reflect.ValueOf(obj))
    50  	r, _ = valueInterface(v.FieldByName(fieldName), false).(T)
    51  	return
    52  }