github.com/searKing/golang/go@v1.2.117/encoding/internal/tag/structTagFunc.go (about) 1 // Copyright 2020 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package tag 6 7 import ( 8 "reflect" 9 10 reflect2 "github.com/searKing/golang/go/reflect" 11 ) 12 13 type structTagFunc struct { 14 fields []field 15 fieldTagFunc []tagFunc 16 } 17 18 func (se *structTagFunc) handle(state *tagState, v reflect.Value, opts tagOpts) (isUserDefined bool) { 19 isUserDefined = false 20 21 for i, f := range se.fields { 22 fv := reflect2.ValueByStructFieldIndex(v, f.index) 23 if !fv.IsValid() && reflect2.IsEmptyValue(fv) { 24 continue 25 } 26 field := v.FieldByIndex(se.fields[i].index) 27 28 //判断是否为可取指,可导出字段 29 if !field.CanAddr() || !field.CanInterface() { 30 continue 31 } 32 33 // continue if a userDefined func has been called 34 if isFieldTagFuncUserDefined := se.fieldTagFunc[i](state, fv, opts); isFieldTagFuncUserDefined { 35 continue 36 } 37 38 tagFn := opts.TagHandler 39 if tagFn != nil { 40 if err := tagFn(field, se.fields[i].structTag); err != nil { 41 state.error(&TaggerError{v.Type(), err}) 42 return 43 } 44 } 45 } 46 return 47 } 48 49 func newStructTagFunc(t reflect.Type) tagFunc { 50 fields := cachedTypeFields(t) 51 se := &structTagFunc{ 52 fields: fields, 53 fieldTagFunc: make([]tagFunc, len(fields)), 54 } 55 for i, f := range fields { 56 se.fieldTagFunc[i] = typeTagFunc(reflect2.TypeByStructFieldIndex(t, f.index)) 57 } 58 return se.handle 59 }