1 Star 0 Fork 0

bughou / go

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
struct.go 1.73 KB
一键复制 编辑 原始数据 按行查看 历史
bughou 提交于 2022-03-24 11:57 . 迁移完成
package funcs
import (
"reflect"
"sync"
"gitee.com/go-better/dev/encoding/jsondoc/encoder/types"
)
func newStructEncoder(t reflect.Type) encoderFunc {
se := structEncoder{fields: cachedTypeFields(t)}
return se.encode
}
type structEncoder struct {
fields []field
}
func (se structEncoder) encode(buf *types.Buffer, v reflect.Value, opts types.Options) {
buf.WriteByte('{')
if len(se.fields) > 0 {
opts.WriteCommentIfPresent(buf)
}
needComma := false
lastFieldOpts := types.Options{}
fieldLoop:
for i := range se.fields {
f := &se.fields[i]
nextLayerOpts := opts // options for next layer
// Find the nested struct field by following f.index.
fv := v
for _, i := range f.index {
if fv.Kind() == reflect.Ptr {
if fv.IsNil() {
typ := fv.Type()
if opts.NotRecursion(typ) {
fv = reflect.New(typ.Elem())
nextLayerOpts.AppendConvertedTypeInUpperLayers(typ)
} else {
continue fieldLoop
}
}
fv = fv.Elem()
}
fv = fv.Field(i)
}
if needComma {
buf.WriteByte(',')
lastFieldOpts.WriteCommentIfPresent(buf)
}
if nextLayerOpts.EscapeHTML {
buf.WriteString(f.nameEscHTML)
} else {
buf.WriteString(f.nameNonEsc)
}
nextLayerOpts.Quoted = f.quoted
nextLayerOpts.SetComment(f.comment, f.commentHTML)
f.encoder(buf, fv, nextLayerOpts)
needComma = true
lastFieldOpts = nextLayerOpts
}
lastFieldOpts.WriteCommentIfPresent(buf)
buf.WriteByte('}')
}
var fieldCache sync.Map // map[reflect.Type][]field
// cachedTypeFields is like typeFields but uses a cache to avoid repeated work.
func cachedTypeFields(t reflect.Type) []field {
if f, ok := fieldCache.Load(t); ok {
return f.([]field)
}
f, _ := fieldCache.LoadOrStore(t, typeFields(t))
return f.([]field)
}
Go
1
https://gitee.com/bughou/go.git
git@gitee.com:bughou/go.git
bughou
go
go
d31700df43a9

搜索帮助

53164aa7 5694891 3bd8fe86 5694891