golang递归地反映字段类型和值

2024-01-16

在golang中,我想通过结构体递归地反映,获取字段的名称、类型和值。

这里的代码帮助我反思golang递归反射 https://stackoverflow.com/questions/47624318/golang-recurisive-reflection/47625992?noredirect=1#comment82247395_47625992

问题是,当我尝试提取值时,当我将该值反映在 ptr 值上时,我会不断出现恐慌。 是否可以反映类型,并继续传递值,直到到达基元,然后打印字段名称、类型和值?

这是我修改的代码:

    func printType(prefix string, t reflect.Type, v reflect.Value visited map[reflect.Type]bool) {

    // Print the name of this type with opening ( for description.
    fmt.Printf("%s (", t)

    // Traverse elements, adding to description as we go.
elems:
    for {
        switch t.Kind() {
        case reflect.Ptr:
            fmt.Print("ptr to ")
        case reflect.Slice:
            fmt.Print("slice of ")
        case reflect.Array:
            fmt.Printf("array with %d elements of ", t.Len())
        default:
            break elems
        }
        t = t.Elem()
    }

    // Print the kind of the type and the closing ) of the description.
    // In the case of a struct, we print the names of the fields and recurse.
    switch t.Kind() {
    case reflect.Struct:
        fmt.Printf("struct with %d fields)\n", t.NumField())
        if visited[t] {
            // Don't blow up on recursive type definition.
            break
        }
        visited[t] = true
        prefix += "    "
        for i := 0; i < t.NumField(); i++ {
            f := t.Field(i)
            // Get value for field
            fieldValue := v.Field(i)

            fmt.Print(prefix, f.Name, " ")
            printType(prefix, f.Type, fieldValue, visited)
        }
    default:
        fmt.Printf("%s) : %s\n", t.Kind(), v)
    }
}

当我运行这个时,我在调用 fieldValue := v.Field(i) 时感到恐慌 关于如何实现这一目标有什么想法吗?

Thanks


尝试这个:

func printValue(prefix string, v reflect.Value, visited map[interface{}]bool) {

    fmt.Printf("%s: ", v.Type())

    // Drill down through pointers and interfaces to get a value we can print.
    for v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface {
        if v.Kind() == reflect.Ptr {
            // Check for recursive data
            if visited[v.Interface()] {
                fmt.Println("visted")
                return
            }
            visited[v.Interface()] = true
        }
        v = v.Elem()
    }

    switch v.Kind() {
    case reflect.Slice, reflect.Array:
        fmt.Printf("%d elements\n", v.Len())
        for i := 0; i < v.Len(); i++ {
            fmt.Printf("%s%d: ", prefix, i)
            printValue(prefix+"   ", v.Index(i), visited)
        }
    case reflect.Struct:
        t := v.Type() // use type to get number and names of fields
        fmt.Printf("%d fields\n", t.NumField())
        for i := 0; i < t.NumField(); i++ {
            fmt.Printf("%s%s: ", prefix, t.Field(i).Name)
            printValue(prefix+"   ", v.Field(i), visited)
        }
    case reflect.Invalid:
        fmt.Printf("nil\n")
    default:
        fmt.Printf("%v\n", v.Interface())
    }
}

由于可以从值获取类型,因此无需将类型传递给打印函数。

游乐场示例 https://play.golang.org/p/fqpG6VLk1A

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

golang递归地反映字段类型和值 的相关文章

随机推荐

  • 如何使用 *ngFor 迭代对象键?

    我一直在挖掘 发现我可以使用以下方法在对象上使用 ngFor div div where ObjNgFor管道是 Pipe name ObjNgFor pure false export class ObjNgFor implements
  • XHTML:将 DIV 放置在 A 标记中

    Is it alright将 div 标签放置在锚标签内 div 的内容会将页面重定向到锚标记的 href 吗 将 div 标签放在锚标签内可以吗 Yes if 您正在使用 HTML5 XHTML5 和 锚标记不在内联上下文中 即仅允许短语
  • 如何使用php从url读取xml文件

    我必须从 URL 读取 XML 文件 map url http maps google com maps api directions xml origin merchant address url destination customer
  • 从 PHP 中的函数返回多个值 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我有这个函数 在调用它时返回三个值
  • Union 赋值中的不兼容类型

    Mypy 向我打印以下消息 x py 74 错误 赋值中的类型不兼容 表达式具有类型 Union str Dict str str 变量的类型为 str 是不是很奇怪 str是其一部分Union str Dict str str 代码如下
  • 从 PHP CLI 打开 Vim

    当你从提交命令中删除 m 时 如何从像 svn 和 git 那样的 CLI 打开 vim 我收到以下错误 Vim 警告 输出不是到终端 echo Please edit this file gt file name vim file nam
  • 如何使用 Perl 截取网页屏幕截图?

    是否可以用 Perl 编写一个脚本来打开不同的 URL 并保存每个 URL 的屏幕截图 你可以使用WWW 机械化 Firefox http search cpan org perldoc WWW Mechanize Firefox控制 Fi
  • 使用 FluentNHibernate 映射通用 EntityBase

    我的所有实体类型都有一个基类 就像 public abstract class EntityBase
  • 有谁知道这个Android类的功能吗? “com.google.apps.tiktok.tracing.db”?

    我正在使用 Android Studio Logcat 调试我自己的应用程序 并遇到一些涉及 com google apps tiktok tracing db 类的日志 这和抖音有关系吗 我从未在手机上安装过该应用程序 我的 Logcat
  • 压缩图像的最佳方法 Javascript React Web App

    我正在寻找最佳的解决方案来压缩我收到并需要存储在数据库中的图像 实际上 我将图像转换为base64 然后将其发送到服务器 handleImage e gt e preventDefault let reader new FileReader
  • 带有准备好的语句的 PostgreSQL 内部查询

    我有一个表来存储联系人 我想获取添加 user id 为 some number 的列的最大值 并将其设置为当前插入记录的相同列值 我正在使用准备好的语句 pg prepare db add INSERT INTO CONTACTS c u
  • 重置 FactoryGirl 测试的“序列”

    有谁知道如何重置FactoryGirl的序列方法 我有一个创建任务列表的工厂 我希望每次都从 1 开始 我使用 序列 是因为任务列表是一个关联模型 所以每次使用时我都需要增加顺序FactoryGirl create直到我调用重置 你需要写F
  • 在 Javascript 中检测 MS Surface 虚拟键盘

    有没有办法通过 Javascript 检测 MS Surface 的虚拟键盘何时显示在网页中 虚拟键盘覆盖了页面上的活动文本字段 我需要能够检测到这一点 以便我可以重新布局页面以更好地使用剩余的窗口区域 None
  • 仅通过单击节点图像来展开/折叠 TreeView

    我的表单上有一个包含大量项目 节点的 TreeView 当我双击节点的项目时 我运行一个过程 取决于单击的项目 我的问题是 我希望它仅在单击节点的图标 或 号 时展开 折叠 如果我双击一个项目则不会 类似的问题 http www delph
  • Ant构建执行cordova

    我为我的 cordova 项目创建了一个 ant 构建 如下所示
  • 如何使用 datafactory 管道转换 xml 数据

    我们如何将 XML 负载中的数据保存到 Blob 存储中 input
  • 对于 Jenkins git 插件,建议在哪里运行 git config ?

    在詹金斯的领导下我也有同样的情况longpaths中描述的问题这个线程 https stackoverflow com questions 22575662 filename too long in git for windows This
  • R Markdown 版本的 \framesubtitle?

    以下是我所知道的创建带有字幕的投影仪幻灯片的最少 TeXy 方法 output beamer presentation Title of Slide framesubtitle Subtitle of Slide Frame content
  • C++ 虚拟继承内存布局

    虚拟继承内存布局 我试图完全理解虚拟继承和 vTables vPtrs 的内存幕后发生的事情以及不发生的事情 我有两个我编写的代码示例 我确切地理解它们工作的原因 但我只是想确保我心中对对象内存布局有正确的想法 Here http post
  • golang递归地反映字段类型和值

    在golang中 我想通过结构体递归地反映 获取字段的名称 类型和值 这里的代码帮助我反思golang递归反射 https stackoverflow com questions 47624318 golang recurisive ref