在golang中,我希望以递归方式反映结构,获取字段的名称,类型和值。
这里的代码帮助我反映了golang recurisive reflection
当我在ptr Value上反映值时,问题是当我尝试提取值时,我一直感到恐慌。 是否有可能反映这两种类型,并继续传递值直到我到达基元,并在那时打印字段名称,类型和值?
以下是我修改的代码:
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) 有关如何实现这一目标的任何想法?
由于
答案 0 :(得分:2)
试试这个:
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())
}
}
因为可以从值中获取类型,所以不需要将类型传递给print函数。