The program is:
package main
import (
"fmt"
"reflect"
)
type Request struct {
Method string
Resource string //path
Protocol string
}
type s struct {
ID int
Title string
Request Request
Price float64
Interface interface{}
Exists bool
Many []string
}
func main() {
s := s{}
iterateStruct(s)
}
func iterateStruct(s interface{}) {
e := reflect.ValueOf(s)
for i := 0; i < e.NumField(); i {
varName := e.Type().Field(i).Name
varKind := e.Field(i).Kind()
fmt.Println(e.Type().Field(i).Name)
if varKind == reflect.Struct {
//iterateStruct( <what should be here?>)
}
varType := e.Type().Field(i).Type
varValue := e.Field(i).Interface()
fmt.Printf("%v %v %v %v\n", varName, varKind, varType, varValue)
}
}
Using recursion I'd like to get the same information for Request, that is a structure part of a structure.
What would I need to pass as a parameter? I tried various ways but I have to reckon it's a lot of trial and error for me.
CodePudding user response:
Here's an example that handles fields with pointers to structs, interfaces containing struct value, etc.. As a bonus, this example indents nested structs.
func iterate(v reflect.Value, indent string) {
v = reflect.Indirect(v)
if v.Kind() != reflect.Struct {
return
}
indent = " "
for i := 0; i < v.NumField(); i {
varName := v.Type().Field(i).Name
varKind := v.Field(i).Kind()
varType := v.Type().Field(i).Type
varValue := v.Field(i).Interface()
fmt.Printf("%s%v %v %v %v\n", indent, varName, varKind, varType, varValue)
iterate(v.Field(i), indent)
}
}
Call it like this:
iterate(reflect.ValueOf(s), "")
https://go.dev/play/p/y1CzbKAUvD_w
CodePudding user response:
Try this:
if varKind == reflect.Struct {
iterateStruct(e.Field(i).Interface())
}
e.Field(i) returns the Value for the struct field. Interface{} will return the underlying value, so you can call iterateStruct using that.
