I have a function that iterates through all the interface fields passed as a parameter. For this, I use reflection. The problem is that I do not know how to get the address of a field without a pointer. Here is an example:
type Z struct { Id int } type V struct { Id int FZ } type T struct { Id int FV }
The above code represents my test structures. Now here is the actual function that traverses the specified structure and lists the details about it:
func InspectStruct(o interface{}) { val := reflect.ValueOf(o) if val.Kind() == reflect.Interface && !val.IsNil() { elm := val.Elem() if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr { val = elm } } if val.Kind() == reflect.Ptr { val = val.Elem() } for i := 0; i < val.NumField(); i++ { valueField := val.Field(i) typeField := val.Type().Field(i) address := "not-addressable" if valueField.Kind() == reflect.Interface && !valueField.IsNil() { elm := valueField.Elem() if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr { valueField = elm } } if valueField.Kind() == reflect.Ptr { valueField = valueField.Elem() } if valueField.CanAddr() { address = fmt.Sprint(valueField.Addr().Pointer()) } fmt.Printf("Field Name: %s,\t Field Value: %v,\t Address: %v\t, Field type: %v\t, Field kind: %v\n", typeField.Name, valueField.Interface(), address, typeField.Type, valueField.Kind()) if valueField.Kind() == reflect.Struct { InspectStruct(valueField.Interface()) } } }
And here is the actual test after creating / initializing the structure:
t := new(T) t.Id = 1 tF = *new(V) tFId = 2 tFF = *new(Z) tFFId = 3 InspectStruct(t)
And finally, the output of the InspectStruct call:
Field Name: Id, Field Value: 1, Address: 408125440 , Field type: int , Field kind: int Field Name: F, Field Value: {2 {3}}, Address: 408125444 , Field type: main.V , Field kind: struct Field Name: Id, Field Value: 2, Address: not-addressable , Field type: int , Field kind: int Field Name: F, Field Value: {3}, Address: not-addressable , Field type: main.Z , Field kind: struct Field Name: Id, Field Value: 3, Address: not-addressable , Field type: int , Field kind: int
As you can see, I use recursion, so if one of the fields is a view of the structure, I call InspectStruct for it. My problem is that although all the fields were initialized for the entire hierarchy βtβ of the whole structure, I canβt get the address for any field located at a deeper depth than βtβ. I would really appreciate any help.