Guest User

Untitled

a guest
Jul 19th, 2018
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.31 KB | None | 0 0
  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. }
Add Comment
Please, Sign In to add comment