【问题标题】:What would be a good way to dynamically find out what is inside a struct?什么是动态找出结构内部内容的好方法?
【发布时间】:2014-06-06 16:24:12
【问题描述】:

如果我在 Go 中有以下结构:

type Person struct {
    name string
    age  int
}

鉴于我们不知道 Person 结构的组成部分,我们如何以编程方式找出?我环顾四周,似乎可以使用反射来做到这一点?

即使只是获取结构数据的键也是一个开始,因为类型 []string 但理想情况下获取类型也很有用。

【问题讨论】:

  • 反思更有可能是最好的方法。你能发布一些你到目前为止尝试过的 codw 吗?
  • 我实际上还没有任何东西要发布。我仍在努力了解可以完成的各种方式。目前处于死胡同。

标签: types struct go


【解决方案1】:

您确实可以使用反射来做到这一点。你主要想要reflect.TypeOfreflect.Type.Fieldreflect.Type.NumFieldreflect.StructField

代码:

package main

import "fmt"
import "reflect"

type Person struct {
    name string
    age  int
}

func main() {
    typ := reflect.TypeOf(Person{})
    for i := 0; i < typ.NumField(); i++ {
        field := typ.Field(i)
        fmt.Println("Field name:", field.Name)
        fmt.Println("Field type:", field.Type)
        fmt.Println()
    }
}

Playground link

一些注意事项:

  • 这适用于包中和包外的结构
  • 如果您需要实际更改或读取数据,请使用 reflect.ValueOf 并将 指针 传递给结构,然后调用 Value.Elem()
  • 您不能通过反射设置另一个包中未导出的字段而不会出现恐慌 (well, okay, you can, but it involves unsafe and ain't pretty),但您可以读取它们。不建议这样做。
  • 在使用反射之前,请务必考虑是否真的需要反射。目前,你需要有 Go 源码才能成功导入包,所以如果你只需要知道字段名称,最好只浏览源代码。如果您需要在运行时知道,请问自己为什么以及是否有任何可能的解决方法。 Reflect 是一个充满错误和古怪行为的地雷。

【讨论】:

  • 完美运行,似乎是一个优雅的解决方案!
  • 很好的答案,但我不同意最后一点,大部分时间都不需要反射,而且速度很慢,但是如果使用得当,它既不是错误的,也不是古怪的。例如你需要它用于 json/gob/xml/mgo.bson 等。
  • @OneOfOne 我的意思是对于很多人来说很难做到正确。它有很多行为,如果你知道的话,这些行为是完全有意义的,但不是很明显(比如传递指向 ValueOf 的指针,然后调用 Elem 之类的东西;它处理嵌入式类型的方式也可以是有点不稳定)。我并不是在暗示反射本身是错误的或古怪的,只是如果您不知道自己在做什么,您可能会遇到古怪和错误的行为,因为您并没有真正了解它在做什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-09
  • 2019-04-09
  • 1970-01-01
  • 2019-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多