From ad6e4c7491c769079cbfa2da67d51c511b314194 Mon Sep 17 00:00:00 2001 From: zhoujie Date: Fri, 28 Nov 2025 13:45:19 +0800 Subject: [PATCH] perf(scan): flattenDataToPtrs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 减少了循环次数 优化了名称 --- mapping.go | 51 +++++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/mapping.go b/mapping.go index 3c55d0b..9dd61e9 100644 --- a/mapping.go +++ b/mapping.go @@ -231,63 +231,66 @@ func (b *Mapper) extractTableMaterial(data ...any) (map[string][]*TableRowMateri return result, nil } -// normalizeData 对输入数据进行统一处理和规范化 +// flattenDataToPtrs 对输入数据中不同类型的数据统一转换为指针形式,并展平切片/数组类型的数据 // 支持输入为任意数量的参数,参数可以是单个结构体指针或结构体,也可以是结构体切片或指针切片 // 处理逻辑包括: // 1. 将切片类型的参数拆开放入一个统一的一维切片中(展平) // 2. 跳过其中的 nil 元素,确保数据有效性 // 3. 将所有非指针类型的元素转换为对应的指针类型,方便后续统一处理 -func (b *Mapper) normalizeData(data ...any) []any { - var normalizedData []any +func (b *Mapper) flattenDataToPtrs(data ...any) ([]any, error) { + var flattenedData = make([]any, 0, len(data)) for _, item := range data { - if isNil(item) { - // 跳过nil值,避免后续反射调用panic + if isNil(item) { // 跳过nil值,避免后续反射调用panic continue } itemType := reflect.TypeOf(item) + + if itemType.Kind() == reflect.Ptr || itemType.Kind() == reflect.Struct { + // 非切片类型直接追加 指针 + flattenedData = append(flattenedData, ensurePtr(item)) + continue + } + if itemType.Kind() == reflect.Slice || itemType.Kind() == reflect.Array { // 处理切片类型参数,展平成单个元素 sliceValue := reflect.ValueOf(item) for i := 0; i < sliceValue.Len(); i++ { elem := sliceValue.Index(i).Interface() - if isNil(elem) { - // 跳过nil元素 + if isNil(elem) { // 跳过nil元素 continue } - normalizedData = append(normalizedData, elem) + // 非切片类型直接追加 指针 + flattenedData = append(flattenedData, ensurePtr(elem)) } - } else { - // 非切片类型直接追加 - normalizedData = append(normalizedData, item) - } - } - - // 转换所有元素为指针类型,便于后续一致性处理 - for i, item := range normalizedData { - if isNil(item) { continue } - normalizedData[i] = ensurePtr(item) + + return nil, fmt.Errorf("unsupported data type: %s, expected struct, pointer, slice or array", itemType.String()) + } - return normalizedData + + return flattenedData, nil } func (b *Mapper) ToInsertSQL(data ...any) (string, error) { - // 统一规范化处理输入数据,将切片拆平并转换元素为指针 - normalizedData := b.normalizeData(data...) + // 展平数据为指针切片 + flattenedData, err := b.flattenDataToPtrs(data...) + if err != nil { + return "", fmt.Errorf("failed to flatten data: %w", err) + } - if len(normalizedData) == 0 { + if len(flattenedData) == 0 { return "", fmt.Errorf("data is empty") } // 扫描 struct 类型数据 - if err := b.scanStruct(normalizedData...); err != nil { + if err := b.scanStruct(flattenedData...); err != nil { return "", fmt.Errorf("failed to analyzeStruct struct: %w", err) } // 提取 struct 内的信息 - tableMap, err := b.extractTableMaterial(normalizedData...) + tableMap, err := b.extractTableMaterial(flattenedData...) if err != nil { return "", fmt.Errorf("failed to extract struct data: %w", err) }