2017-12-05 7 views
-1

golang에서 구조체를 통해 재귀 적으로 필드의 이름, 유형 및 값을 가져 와서 반영하고 싶습니다. golang은 재귀 적으로 두 유형의 필드와 값을 모두 반영합니다.

이 코드는 여기에 내가 내가 PTR 값에 대한 가치를 반영 할 때 나는 패닉가 계속 값을 추출 할 때 나에게 문제가 golang recurisive reflection

반영 도왔다. 형식을 모두 반영 할 수 있으며, 프리미티브에 도달 할 때까지 계속 값을 전달하고 그 시점에서 필드 이름, 형식 및 값을 모두 인쇄 할 수 있습니까? = v.Field (I) 이를 달성하는 방법에 대한 어떤 생각 : 나는 fieldValue의를 호출 할 때 나는 공황을 받기를 실행하면

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) 
    } 
} 

: 여기

내가 수정 한 코드?

답변

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()) 
    } 
} 

이 값에서 유형을 얻을 수이기 때문에이 인쇄 기능 유형을 통과 할 필요가 없습니다.

playground example