我正在编写一个递归函数,它遍历结构中的每个原始字段。
我需要能够支持结构字段、结构指针、字段和字段指针。
我试过做这样的事情,对于每个字段,我首先检查它是否是一个指针。如果是,我会打开它的类型,而不仅仅是字段本身。
//Get reflect values and types
valOf := reflect.ValueOf(dest).Elem()
typeOf := valOf.Type()
//Iterate through each field
for i := 0; i < valOf.NumField(); i++ {
var fieldValDeref reflect.Value
//Get reflect value and type of single field
fieldVal := valOf.Field(i)
fieldTyp := typeOf.Field(i)
//Check if field is a pointer. If so, dereference and switch on dereferenced type
if fieldVal.Kind() == reflect.Ptr {
fieldValDeref = fieldVal.Elem()
} else {
fieldValDeref = fieldVal
}
switch fieldValDeref.Kind() {
case reflect.Array, reflect.Chan, reflect.Interface, reflect.Func, reflect.Map, reflect.UnsafePointer:
return errors.New("invalid destination field: " + fieldTyp.Name)
case reflect.Struct:
//Recursive call
break
default:
//Perform Action on Field
..................................
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是,调用后任何指针、结构与否的类型.Elem()都是reflect.Invalid.
我如何首先取消引用一个字段(如果它是一个指针),然后相应地执行操作,无论该字段是结构体还是基元?
谢谢
正如mkopriva 所提到的,取消引用 nil 指针将始终返回reflect.Invalid。解决方案是先创建一个新实例。
if fieldVal.Kind() == reflect.Ptr {
fieldVal.Set(reflect.New(fieldVal.Type().Elem()))
fieldValDeref = fieldVal.Elem()
} else {
fieldValDeref = fieldVal
}
Run Code Online (Sandbox Code Playgroud)