Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "fmt"
- "reflect"
- )
- type MultiQuestions struct {
- QuestionId int64
- QuestionType string
- QuestionText string
- SubMQ SubMultiQuestions
- }
- type SubMultiQuestions struct{}
- func (q *MultiQuestions) StructAttrName() string {
- return reflect.Indirect(reflect.ValueOf(q)).Type().Field(3).Name
- }
- func main() {
- fmt.Println((&MultiQuestions{}).StructAttrName())
- fmt.Println(Fields(&MultiQuestions{}))
- fmt.Println(Fields(MultiQuestions{}))
- }
- // Fields returns a slice of field names. A struct tag with the content of "-"
- // ignores the checking of that particular field. Example:
- //
- // // Field is ignored by this package.
- // Field bool `structure:"-"`
- //
- // Note that only exported fields of a struct can be accessed, non exported
- // fields will be neglected. It panics if s's kind is not struct.
- func Fields(s interface{}) []string {
- v, fields := strctInfo(s)
- keys := make([]string, 0)
- for i, field := range fields {
- val := v.Field(i)
- if IsStruct(val.Interface()) {
- // look out for embedded structs, and convert them to a
- // []string to be added to the final values slice
- for _, embeddedVal := range Fields(val.Interface()) {
- keys = append(keys, embeddedVal)
- }
- }
- keys = append(keys, field.Name)
- }
- return keys
- }
- // IsStruct returns true if the given variable is a struct or a pointer to
- // struct.
- func IsStruct(s interface{}) bool {
- t := reflect.TypeOf(s)
- if t.Kind() == reflect.Ptr {
- t = t.Elem()
- }
- return t.Kind() == reflect.Struct
- }
- // strctInfo returns the struct value and the exported struct fields for a
- // given s struct. This is a convenient helper method to avoid duplicate code
- // in some of the functions.
- func strctInfo(s interface{}) (reflect.Value, []reflect.StructField) {
- v := strctVal(s)
- t := v.Type()
- f := make([]reflect.StructField, 0)
- for i := 0; i < t.NumField(); i++ {
- field := t.Field(i)
- // we can't access the value of unexported fields
- if field.PkgPath != "" {
- continue
- }
- // don't check if it's omitted
- if tag := field.Tag.Get("structure"); tag == "-" {
- continue
- }
- f = append(f, field)
- }
- return v, f
- }
- func strctVal(s interface{}) reflect.Value {
- v := reflect.ValueOf(s)
- // if pointer get the underlying element≤
- if v.Kind() == reflect.Ptr {
- v = v.Elem()
- }
- if v.Kind() != reflect.Struct {
- panic("not struct")
- }
- return v
- }
Add Comment
Please, Sign In to add comment