Home > database >  Obtain structure info
Obtain structure info

Time:01-08

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.

  •  Tags:  
  • Related