gpt4 book ai didi

golang递归反射

转载 作者:IT王子 更新时间:2023-10-29 02:10:49 24 4
gpt4 key购买 nike

我试图递归地反射(reflect)一个结构,打印出每个字段的类型。如果字段是结构的一部分,我希望能够识别数组中保存的类型,然后反射(reflect)该类型。

这是一些示例代码

package main

import (
"log"
"reflect"
)

type child struct {
Name *string
Age int
}

type Parent struct {
Name string
Surname *string
Children []*child
PetNames []string
}

func main() {

typ := reflect.TypeOf(Parent{})
log.Printf("This is a : %s", typ.Kind())

for i := 0; i < typ.NumField(); i++ {
p := typ.Field(i)
if !p.Anonymous {
switch p.Type.Kind() {
case reflect.Ptr:
log.Printf("Ptr: %s is a type %s", p.Name, p.Type)
case reflect.Slice:
log.Printf("Slice: %s is a type %s", p.Name, p.Type)
subtyp := p.Type.Elem()
if subtyp.Kind() == reflect.Ptr {
subtyp = subtyp.Elem()
}
log.Printf("\tDereferenced Type%s", subtyp)
default:
log.Printf("Default: %s is a type %s", p.Name, p.Type)
}
}
}

}

输出如下所示:

This is a : struct
Default: Name is a type string
Ptr: Surname is a type *string
Slice: Children is a type []*main.child
Dereferenced Type main.child
Slice: PetNames is a type []string
Dereferenced Type string

当我确定一个字段类型是指针的一部分时,我可以通过调用 subtype.Elem() 来推断类型。

输出是'main.child'

如果我然后尝试反射(reflect) child 使用

subSubType := reflect.TypeOf(subtyp)
log.Printf("%+v", subSubType)

我得到以下信息:

 *reflect.rtype

如何使用反射 API 迭代子结构的字段?

最佳答案

这是一种方法。

func printType(prefix string, t reflect.Type, 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)
fmt.Print(prefix, f.Name, " ")
printType(prefix, f.Type, visited)
}
default:
fmt.Printf("%s)\n", t.Kind())
}
}

func main() {
printType("", reflect.TypeOf(Parent{}), make(map[reflect.Type]bool))
}

给定以下类型的 Parent{} 的输出:

type child struct {
Name *string
Age int
}

type Parent struct {
Name string
Surname *string
Children []*child
PetNames []string
Parents [2]*Parent
child
}

是:

main.Parent (struct with 6 fields)
Name string (string)
Surname *string (ptr to string)
Children []*main.child (slice of ptr to struct with 2 fields)
Name *string (ptr to string)
Age int (int)
PetNames []string (slice of string)
Parents [2]*main.Parent (array with 2 elements of ptr to struct with 6 fields)
child main.child (struct with 2 fields)

playground example

关于golang递归反射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47624318/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com