英文:
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 (
"fmt"
reflect "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{})
}
答案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 < t.NumField(); i++ {
sf := t.Field(i)
fmt.Println(prefix, sf.Name)
getFields(sf.Type, prefix+" ")
}
}
}
Use it like this:
getFields(reflect.TypeOf(&Example{}), "")
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论