使用反射从深度嵌套的结构中提取标签

Dikshant Adhikari:

我正在尝试从一些深层嵌套的结构中提取一些标签。这些结构是从protobuf消息生成的,并且包含json标签。

我有一个指向结构的指针,该结构可能包含一个结构,该结构包含我可能想要其标签的字段。我可以使用类型进行迭代以获取结构的字段,但是当遇到指针字段时,如何获取其值然后递归?

// Struct has hierarchy like this 
a := &somepb.UpdateRequest{
        Updates: []*somepb.UpdateRequest_Foo{
            &somepb.UpdateRequest_Foo{
                Id: 1,
                Foo: &somepb.FooInfo{
                    Metadata: &somepb.Metadata{
                        Name:        "Foo",
                        Description: "Bar",
                    },
                    Some:    "s",
                    Things:  "o",
                    Are:     "m",
                    Broken:  "e",
                    Here:    "p",
                },
            },
        },
 } 

// ParseStruct parses struct tags of given object
func ParseStruct(obj interface{}, tag string) {
    r := reflect.ValueOf(obj)
    if r.Kind() == reflect.Ptr {
        obj = r.Elem().Interface()
    }
    rv := reflect.TypeOf(obj)
    for i := 0; i < rv.NumField(); i++ {
        f := rv.Field(i)
        // This is to avoid getting tags for Metadata itself (from the struct above)
        // which is *Metadata, I want the tags for Name and Description
        // inside *Metadata instead
        if f.Type.Kind() == reflect.Ptr {
            value := f.Tag.Get(tag)
            if len(value) == 0 {
                continue
            }
            fmt.Println(value)
        }
    }
} 
叶蜂

双方reflect.Typereflect.Value有一个Elem()方法。根据文件

Elem的方法Type

// Elem returns a type's element type.
// It panics if the type's Kind is not Array, Chan, Map, Ptr, or Slice.
Elem() Type

Value.Elem

func (v Value) Elem() Value

Elem returns the value that the interface v contains or that the pointer v points to. It panics if v's Kind is not Interface or Ptr. It returns the zero Value if v is nil. 

您可以使用Elem()方法获取指针的内容,然后使用内容进行递归。但是,鉴于您的原始API是func(interface{},string),您需要使用Value.Elem().Interface()来获取有意义的interface{}但是,相反,我建议您更改API以接受reflect.Type-因为这对于标记提取最为清楚。

示例代码:

func ParseStruct(t reflect.Type, tag string) {
    if t.Kind() == reflect.Ptr {
        t = t.Elm()
    }
    if t.Kind() != reflect.Struct {
        return
    }

    for i := 0; i < t.NumField(); i++ {
        f := t.Field(i)
        value := f.Tag.Get(tag)
        ft := t.Type
        if ft.Kind() == reflect.Ptr {
            ft = ft.Elem()
        }

        // It seems that you don't want a tag from an struct field; only other fields' tags are needed
        if ft.Kind() != reflect.Struct {
            if len(value) != 0 {
                fmt.Println(value)
            }
            continue
        }

        ParseStruct(ft,tag)
    }
}

请注意,此代码非常简单-它不会处理切片或地图中的结构标签。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

美丽的汤:从深度嵌套的<div>中提取

从平面列表中提取嵌套的对象结构

如何从此 JSON 中提取嵌套标签?

如何从嵌套标签的页面中提取文本

使用反射读取嵌套结构

如何在Ansible中从字典中提取深度嵌套的数据

从深度嵌套的JSON文件中提取值(Wikipedia API)

使用 PHP 从 ACF 中提取嵌套的转发器内容 - 关闭标签问题

使用嵌套结构在 Swift 中解码深度嵌套的对象

从 Go 结构中提取标签作为 reflect.Value

使用python从嵌套json中提取

使用xpath从嵌套的div中提取文本

尝试使用 Python 从标签中提取“文本”

使用漂亮的汤从标签中提取“ href”

如何使用反射来设置嵌套的结构域值

从结构中提取数据?

如何使用 Python 在深度嵌套的结构中收集特定值

如何使用 Beautiful Soup 提取深度嵌套的 <p> 標籤

查询以从 Presto 中深度嵌套的 json 数组对象中提取 id

使用 Python 访问 HTML <script> 标签内深度嵌套的数据

阅读深度嵌套的集合结构

PySpark:如何从嵌套在数组内部结构中的结构中提取变量?

从标签中提取多个标签

深度嵌套的JSON标签值

在 Python 中提取 XML 标签并保留标签顺序和层次结构

使用AVX从结构中提取整数和短裤?

从zip中提取文件,而不使用python ZipFile保留结构?

使用Scala从Spark的数组数组中的结构中提取值

如何使用索引從以下嵌套字典中提取“hello”?