我正在尝试使用反射在 Golang 中解析结构体字段指针。

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

I'm trying to parse a struct field pointers with reflection in Golang

问题

所以我想要在一个结构体中打印出名称(可以是嵌套的),所以我尝试使用递归方法来实现,但是我无法成功。我已经粘贴了下面的代码,并且我得到了以下错误信息:"panic: reflect: call of reflect.Value.NumField on zero Value"。当结构体是扁平层次结构时,我可以做到这一点,但是当它是嵌套的时候就失败了。任何帮助都将不胜感激。我还参考了这篇帖子"https://www.reddit.com/r/golang/comments/g254aa/parse_struct_field_pointers_with_reflection_in/"。另外,该结构体是从protobuf构建的,因此使用了Ptr。

package main

import (
	"fmt"
	"reflect"
)

func check(e error) {
	if e != nil {
		panic(e)
	}
}

func getFields(protoStructure interface{}) {
	val := reflect.ValueOf(protoStructure).Elem()
	// if val.Kind() == reflect.Ptr {
	// val = val.Elem()
	// }
	valNumFields := val.NumField()
	for i := 0; i < valNumFields; i++ {
		field := val.Field(i)
		fieldKind := field.Kind()
		varDescription := val.Type().Field(i).Tag.Get("description")
		// fieldKindStr := field.Kind().String()
		fieldName := val.Type().Field(i).Name
		// fieldTypeStr := field.Type().String()
		fmt.Println(fieldName, varDescription)
		if fieldKind == reflect.Ptr {
			rvAsserted := field
			getFields(rvAsserted.Interface())
			// fmt.Println(rvAsserted.Type().String())
		}
	}
	return
}

func main() {
	getFields(&DeviceEnv{})
}
英文:

So i want to print the names in a struct(it can be nested), so i'm trying to use a recursive method to do the same but i'm failing to do so.Ive pasted the code below and i get the following error "panic: reflect: call of reflect.Value.NumField on zero Value". I'm able to do it when it's a flat hierarchy but failing when its nested.Any help is appreciated.Also i used this post "https://www.reddit.com/r/golang/comments/g254aa/parse_struct_field_pointers_with_reflection_in/" for reference. Also, the struct is built from protobuf hence the Ptr.

package main

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

func check(e error) {
	if e != nil {
		panic(e)
	}
}
func getFields(protoStructure interface{}) {
	val := reflect.ValueOf(protoStructure).Elem()
	// if val.Kind() == reflect.Ptr {
	// val = val.Elem()
	// }
	valNumFields := val.NumField()
	for i := 0; i &lt; valNumFields; i++ {
		field := val.Field(i)
		fieldKind := field.Kind()
		varDescription := val.Type().Field(i).Tag.Get(&quot;description&quot;)
		// fieldKindStr := field.Kind().String()
		fieldName := val.Type().Field(i).Name
		// fieldTypeStr := field.Type().String()
		fmt.Println(fieldName, varDescription)
		if fieldKind == reflect.Ptr {
			rvAsserted := field
			getFields(rvAsserted.Interface())
			// fmt.Println(rvAsserted.Type().String())
		}
	}
	return
}
func main() {
	getFields(&amp;DeviceEnv{})
}

答案1

得分: 1

请注意,我是一个语言模型,我无法直接运行代码。以下是您提供的代码的翻译:

// 使用 reflect.Type 作为参数编写一个函数。对指针和结构体字段进行递归操作。

func getFields(t reflect.Type, prefix string) {
    switch t.Kind() {
    case reflect.Ptr:
        getFields(t.Elem(), prefix)
    case reflect.Struct:
        for i := 0; i < t.NumField(); i++ {
            sf := t.Field(i)
            fmt.Println(prefix, sf.Name)
            getFields(sf.Type, prefix+"  ")
        }
    }
}

// 使用方法如下:

getFields(reflect.TypeOf(&Example{}), "")

您可以在playground上运行它。

英文:

Write a function with reflect.Type as an argument. Recurse on pointers and struct fields.

func getFields(t reflect.Type, prefix string) {
	switch t.Kind() {
	case reflect.Ptr:
		getFields(t.Elem(), prefix)
	case reflect.Struct:
		for i := 0; i &lt; t.NumField(); i++ {
			sf := t.Field(i)
			fmt.Println(prefix, sf.Name)
			getFields(sf.Type, prefix+&quot;  &quot;)
		}
	}
}

Use it like this:

getFields(reflect.TypeOf(&amp;Example{}), &quot;&quot;)

Run it on the playground

huangapple
  • 本文由 发表于 2022年6月23日 00:33:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/72719070.html
匿名

发表评论

匿名网友

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

确定