github.com/zhongdalu/gf@v1.0.0/g/internal/structs/structs_map.go (about) 1 // Copyright 2019 gf Author(https://github.com/zhongdalu/gf). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/zhongdalu/gf. 6 7 package structs 8 9 import ( 10 "reflect" 11 12 "github.com/zhongdalu/gf/third/github.com/fatih/structs" 13 ) 14 15 // MapField retrieves struct field as map[name/tag]*Field from <pointer>, and returns it. 16 // 17 // The parameter <recursive> specifies whether retrieving the struct field recursively. 18 // 19 // Note that it only retrieves the exported attributes with first letter up-case from struct. 20 func MapField(pointer interface{}, priority []string, recursive bool) map[string]*Field { 21 fieldMap := make(map[string]*Field) 22 fields := ([]*structs.Field)(nil) 23 if v, ok := pointer.(reflect.Value); ok { 24 fields = structs.Fields(v.Interface()) 25 } else { 26 fields = structs.Fields(pointer) 27 } 28 tag := "" 29 name := "" 30 for _, field := range fields { 31 name = field.Name() 32 // Only retrieve exported attributes. 33 if name[0] < byte('A') || name[0] > byte('Z') { 34 continue 35 } 36 fieldMap[name] = field 37 tag = "" 38 for _, p := range priority { 39 tag = field.Tag(p) 40 if tag != "" { 41 break 42 } 43 } 44 if tag != "" { 45 fieldMap[tag] = field 46 } 47 if recursive { 48 rv := reflect.ValueOf(field.Value()) 49 kind := rv.Kind() 50 if kind == reflect.Ptr { 51 rv = rv.Elem() 52 kind = rv.Kind() 53 } 54 if kind == reflect.Struct { 55 for k, v := range MapField(rv, priority, true) { 56 if _, ok := fieldMap[k]; !ok { 57 fieldMap[k] = v 58 } 59 } 60 } 61 } 62 } 63 return fieldMap 64 }