获取结构信息

huangapple go评论82阅读模式
英文:

Obtain structure info

问题

程序如下:

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(e.Field(i).Interface())
		}
		varType := e.Type().Field(i).Type
		varValue := e.Field(i).Interface()
		fmt.Printf("%v %v %v %v\n", varName, varKind, varType, varValue)
	}

}

使用递归,我想要获取Request的相同信息,它是一个结构体的一部分。

作为参数,我需要传递什么?我尝试了各种方法,但我必须承认对我来说这是很多的试错过程。

英文:

The program is:

    package main

import (
	&quot;fmt&quot;
	&quot;reflect&quot;
)

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 &lt; 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( &lt;what should be here?&gt;)
		}
		varType := e.Type().Field(i).Type
		varValue := e.Field(i).Interface()
		fmt.Printf(&quot;%v %v %v %v\n&quot;, 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.

答案1

得分: 2

尝试这样写:

if varKind == reflect.Struct {
   iterateStruct(e.Field(i).Interface())
}

e.Field(i) 返回结构体字段的 ValueInterface{} 将返回底层值,因此您可以使用它调用 iterateStruct

英文:

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.

答案2

得分: 2

以下是翻译好的内容:

这是一个处理指向结构体的字段、包含结构体值的接口等的示例。作为额外的奖励,这个示例对嵌套结构体进行了缩进。

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)
	}
}

像这样调用它:

iterate(reflect.ValueOf(s), "")

链接:https://go.dev/play/p/y1CzbKAUvD_w

英文:

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 += &quot;  &quot;
	for i := 0; i &lt; 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(&quot;%s%v %v %v %v\n&quot;, indent, varName, varKind, varType, varValue)
		iterate(v.Field(i), indent)
	}
}

Call it like this:

iterate(reflect.ValueOf(s), &quot;&quot;)

https://go.dev/play/p/y1CzbKAUvD_w

huangapple
  • 本文由 发表于 2022年1月8日 03:19:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/70626138.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定