我试图在Golang中解析带有反射的结构场指针

发布于 2025-02-09 15:10:34 字数 1142 浏览 1 评论 0原文

因此,我想在结构中打印名称(可以嵌套),因此我试图使用递归方法来执行同样的操作,但我没有这样做。错误“恐慌:反射:reflect.value.numfield的呼叫”。当它是一个平坦的层次结构时,我能够做到这一点,但是当它嵌套时会失败。任何帮助都会受到赞赏。此外,我还使用了此帖子。供参考。同样,结构是由Protobuf构建的,因此是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{})
}

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

瀟灑尐姊 2025-02-16 15:10:34

用反射式写入函数作为参数。在指针和结构字段上循环。

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{}), "")

在操场上运行它

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{}), "")

Run it on the playground

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文