daily pastebin goal
68%
SHARE
TWEET

Untitled

a guest Jul 19th, 2018 56 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package main
  2.  
  3. import (
  4.     "fmt"
  5.     "reflect"
  6. )
  7.  
  8. type MultiQuestions struct {
  9.     QuestionId   int64
  10.     QuestionType string
  11.     QuestionText string
  12.     SubMQ        SubMultiQuestions
  13. }
  14.  
  15. type SubMultiQuestions struct{}
  16.  
  17. func (q *MultiQuestions) StructAttrName() string {
  18.     return reflect.Indirect(reflect.ValueOf(q)).Type().Field(3).Name
  19. }
  20.  
  21. func main() {
  22.     fmt.Println((&MultiQuestions{}).StructAttrName())
  23.     fmt.Println(Fields(&MultiQuestions{}))
  24.     fmt.Println(Fields(MultiQuestions{}))
  25. }
  26.  
  27. // Fields returns a slice of field names. A struct tag with the content of "-"
  28. // ignores the checking of that particular field. Example:
  29. //
  30. // // Field is ignored by this package.
  31. // Field bool `structure:"-"`
  32. //
  33. // Note that only exported fields of a struct can be accessed, non exported
  34. // fields will be neglected. It panics if s's kind is not struct.
  35. func Fields(s interface{}) []string {
  36.     v, fields := strctInfo(s)
  37.  
  38.     keys := make([]string, 0)
  39.     for i, field := range fields {
  40.         val := v.Field(i)
  41.         if IsStruct(val.Interface()) {
  42.             // look out for embedded structs, and convert them to a
  43.             // []string to be added to the final values slice
  44.             for _, embeddedVal := range Fields(val.Interface()) {
  45.                 keys = append(keys, embeddedVal)
  46.             }
  47.         }
  48.  
  49.         keys = append(keys, field.Name)
  50.     }
  51.  
  52.     return keys
  53. }
  54.  
  55. // IsStruct returns true if the given variable is a struct or a pointer to
  56. // struct.
  57. func IsStruct(s interface{}) bool {
  58.     t := reflect.TypeOf(s)
  59.     if t.Kind() == reflect.Ptr {
  60.         t = t.Elem()
  61.     }
  62.  
  63.     return t.Kind() == reflect.Struct
  64. }
  65.  
  66. // strctInfo returns the struct value and the exported struct fields for a
  67. // given s struct. This is a convenient helper method to avoid duplicate code
  68. // in some of the functions.
  69. func strctInfo(s interface{}) (reflect.Value, []reflect.StructField) {
  70.     v := strctVal(s)
  71.     t := v.Type()
  72.  
  73.     f := make([]reflect.StructField, 0)
  74.  
  75.     for i := 0; i < t.NumField(); i++ {
  76.         field := t.Field(i)
  77.         // we can't access the value of unexported fields
  78.         if field.PkgPath != "" {
  79.             continue
  80.         }
  81.  
  82.         // don't check if it's omitted
  83.         if tag := field.Tag.Get("structure"); tag == "-" {
  84.             continue
  85.         }
  86.  
  87.         f = append(f, field)
  88.     }
  89.  
  90.     return v, f
  91. }
  92.  
  93. func strctVal(s interface{}) reflect.Value {
  94.     v := reflect.ValueOf(s)
  95.  
  96.     // if pointer get the underlying element≤
  97.     if v.Kind() == reflect.Ptr {
  98.         v = v.Elem()
  99.     }
  100.  
  101.     if v.Kind() != reflect.Struct {
  102.         panic("not struct")
  103.     }
  104.  
  105.     return v
  106. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top