package struc import ( "encoding/binary" "fmt" "io" "reflect" "sync" ) type Options struct { ByteAlign int PtrSize int Order binary.ByteOrder } func (o *Options) Validate() error { if o.PtrSize == 0 { o.PtrSize = 32 } else { switch o.PtrSize { case 8, 16, 32, 64: default: return fmt.Errorf("Invalid Options.PtrSize: %d. Must be in (8, 16, 32, 64)", o.PtrSize) } } return nil } var emptyOptions = &Options{} func init() { // fill default values to avoid data race to be reported by race detector. emptyOptions.Validate() } var prepCache = sync.Map{} // cacheKey 缓存键:区分 结构体/自定义类型/二进制类型,保证缓存唯一性 type cacheKey struct { typ reflect.Type // 数据的基础类型 kind uint8 // 0=结构体, 1=自定义类型, 2=二进制类型 } // prep 优化版:带完整缓存,缓存处理后的最终 Packer func prep(data interface{}) (reflect.Value, Packer, error) { // 1. 提前判空 if data == nil { return reflect.Value{}, nil, fmt.Errorf("Invalid reflect.Value for nil") } // 2. 初始反射值处理(和原逻辑一致) value := reflect.ValueOf(data) elemValue := value for elemValue.Kind() == reflect.Ptr { next := elemValue.Elem().Kind() if next == reflect.Struct || next == reflect.Ptr { elemValue = elemValue.Elem() } else { break } } // 3. 构建缓存键的基础类型(取解引用后的类型) baseType := elemValue.Type() var packer Packer var err error // 4. 按类型分支处理,优先查缓存 switch elemValue.Kind() { case reflect.Struct: // 缓存键:结构体类型 key := cacheKey{typ: baseType, kind: 0} if cacheVal, ok := prepCache.Load(key); ok { // 缓存命中:直接返回缓存的 Packer return elemValue, cacheVal.(Packer), nil } // 缓存未命中:执行原逻辑解析 fields packer, err = parseFields(elemValue) if err != nil { return elemValue, nil, err } // 缓存处理后的 Packer prepCache.Store(key, packer) default: // 非结构体类型:检查有效性 if !elemValue.IsValid() { return reflect.Value{}, nil, fmt.Errorf("Invalid reflect.Value for %+v", data) } // 自定义类型分支 if c, ok := data.(Custom); ok { // 缓存键:自定义类型 key := cacheKey{typ: baseType, kind: 1} if cacheVal, ok := prepCache.Load(key); ok { return elemValue, cacheVal.(Packer), nil } // 构建 customFallback 并缓存 // 仅用 custom Custom 构建,完全匹配你的定义 packer = customFallback{custom: c} prepCache.Store(key, packer) } else { // 二进制类型分支 // 缓存键:二进制类型 key := cacheKey{typ: baseType, kind: 2} if cacheVal, ok := prepCache.Load(key); ok { return elemValue, cacheVal.(Packer), nil } // 构建 binaryFallback 并缓存 packer = binaryFallback(elemValue) prepCache.Store(key, packer) } } // 5. 返回和原逻辑完全一致的结果 return elemValue, packer, err } func Pack(w io.Writer, data interface{}) error { return PackWithOptions(w, data, nil) } func PackWithOptions(w io.Writer, data interface{}, options *Options) error { if options == nil { options = emptyOptions } if err := options.Validate(); err != nil { return err } val, packer, err := prep(data) if err != nil { return err } if val.Type().Kind() == reflect.String { val = val.Convert(reflect.TypeOf([]byte{})) } size := packer.Sizeof(val, options) // if size == 0 { // fmt.Println("size==0") // } buf := make([]byte, size) if _, err := packer.Pack(buf, val, options); err != nil { return err } _, err = w.Write(buf) return err } func Unpack(r io.Reader, data interface{}) error { return UnpackWithOptions(r, data, nil) } func UnpackWithOptions(r io.Reader, data interface{}, options *Options) error { if options == nil { options = emptyOptions } if err := options.Validate(); err != nil { return err } val, packer, err := prep(data) if err != nil { return err } return packer.Unpack(r, val, options) } func Sizeof(data interface{}) (int, error) { return SizeofWithOptions(data, nil) } func SizeofWithOptions(data interface{}, options *Options) (int, error) { if options == nil { options = emptyOptions } if err := options.Validate(); err != nil { return 0, err } val, packer, err := prep(data) if err != nil { return 0, err } return packer.Sizeof(val, options), nil }