Files
gf/util/gconv/internal/structcache/structcache_cached.go
hailaz ee24da4e72 refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
This pull request standardizes the use of the Go 1.18+ `any` type alias
instead of `interface{}` throughout the codebase. The change improves
code readability and aligns with modern Go best practices. The update
touches many files, including core data structures, code generation
templates, logging utilities, and test data, ensuring consistency across
all usages.

**Type alias migration to `any`:**

* Replaced all instances of `interface{}` with `any` in core data
structures such as `garray` and in generated model structs (e.g.,
`TableUser`, `User1`, `User2`) to modernize type usage.
[[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31)
[[2]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19)
[[3]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18)
[[4]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19)
[[5]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19)
[[6]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19)
* Updated function signatures, method parameters, and return types from
`interface{}` to `any` in various parts of the codebase, including code
generation, service logic, and logging utilities (e.g., `mlog`).
[[1]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55)
[[2]](diffhunk://#diff-2b1953fb78cf3593d8c2c7d911e95b65fd0b847c30ed0b4d167d16fe6d781235L54-R74)
[[3]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73)
[[4]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41)
[[5]](diffhunk://#diff-c5d51d56f487779a2b6207c7ad26c7a20bbadcc846ce094fe60ab4cabff58c51L107-R107)
[[6]](diffhunk://#diff-f96e6a9fdb416eb1804ceaba1fe0ac637bff22c43837f8bb849c2366ce72d4a1L116-R121)
[[7]](diffhunk://#diff-f94c83a1b08ae060d9346f4a6031fc4a7b9a0b894e02d9afaa09018b6598eac0L112-R112)
[[8]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L36-R36)
[[9]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L74-R74)
[[10]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L96-R96)

**Generated code and templates:**

* Adjusted generated files and code generation templates to output `any`
instead of `interface{}` for relevant struct fields and function
signatures, ensuring that new code generation aligns with the updated
convention.
[[1]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19)
[[2]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18)
[[3]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19)
[[4]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19)
[[5]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19)
[[6]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55)
[[7]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73)
[[8]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41)

**Container and utility updates:**

* Refactored the `garray` container implementation and related
constructors/methods to use `[]any` instead of `[]interface{}`, along
with corresponding function signatures.
[[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31)
[[2]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L52-R52)
[[3]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L62-R62)
[[4]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L73-R86)
[[5]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L96-R97)
[[6]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L107-R114)
[[7]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L124-R124)
[[8]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L135-R143)
[[9]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L167-R167)

These changes collectively modernize the codebase and prepare it for
future Go developments by using the idiomatic `any` type.
2025-08-28 16:53:19 +08:00

119 lines
4.0 KiB
Go

// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package structcache
import (
"reflect"
"github.com/gogf/gf/v2/internal/utils"
"github.com/gogf/gf/v2/util/gtag"
)
// GetCachedStructInfo retrieves or parses and returns a cached info for certain struct type.
// The given `structType` should be type of struct.
func (cf *Converter) GetCachedStructInfo(structType reflect.Type, priorityTag string) *CachedStructInfo {
if structType.Kind() != reflect.Struct {
return nil
}
// check if it has been cached.
cachedStructInfo, ok := cf.getCachedConvertStructInfo(structType)
if ok {
// directly returns the cached struct info if already exists.
return cachedStructInfo
}
// else create one.
// it parses and generates a cache info for given struct type.
cachedStructInfo = NewCachedStructInfo(cf)
var (
priorityTagArray []string
parentIndex = make([]int, 0)
)
if priorityTag != "" {
priorityTagArray = append(utils.SplitAndTrim(priorityTag, ","), gtag.StructTagPriority...)
} else {
priorityTagArray = gtag.StructTagPriority
}
cf.parseStructToCachedStructInfo(structType, parentIndex, cachedStructInfo, priorityTagArray)
cf.storeCachedStructInfo(structType, cachedStructInfo)
return cachedStructInfo
}
func (cf *Converter) storeCachedStructInfo(structType reflect.Type, cachedStructInfo *CachedStructInfo) {
// Temporarily enabled as an experimental feature
cf.cachedStructsInfoMap.Store(structType, cachedStructInfo)
}
func (cf *Converter) getCachedConvertStructInfo(structType reflect.Type) (*CachedStructInfo, bool) {
// Temporarily enabled as an experimental feature
v, ok := cf.cachedStructsInfoMap.Load(structType)
if ok {
return v.(*CachedStructInfo), ok
}
return nil, false
}
// parseStructToCachedStructInfo parses given struct reflection type and stores its fields info into given CachedStructInfo.
// It stores nothing into CachedStructInfo if given struct reflection type has no fields.
func (cf *Converter) parseStructToCachedStructInfo(
structType reflect.Type,
fieldIndexes []int,
cachedStructInfo *CachedStructInfo,
priorityTagArray []string,
) {
var (
fieldName string
structField reflect.StructField
fieldType reflect.Type
)
// TODO:
// Check if the structure has already been cached in the cache.
// If it has been cached, some information can be reused,
// but the [FieldIndex] needs to be reset.
// We will not implement it temporarily because it is somewhat complex
for i := 0; i < structType.NumField(); i++ {
structField = structType.Field(i)
fieldType = structField.Type
fieldName = structField.Name
// Only do converting to public attributes.
if !utils.IsLetterUpper(fieldName[0]) {
continue
}
copyFieldIndexes := make([]int, len(fieldIndexes))
copy(copyFieldIndexes, fieldIndexes)
// normal basic attributes.
if structField.Anonymous {
// handle struct attributes, it might be struct/*struct embedded..
if fieldType.Kind() == reflect.Pointer {
fieldType = fieldType.Elem()
}
if fieldType.Kind() != reflect.Struct {
continue
}
// Skip the embedded structure of the 0 field,
if fieldType.NumField() == 0 {
continue
}
if structField.Tag != "" {
// Do not add anonymous structures without tags
cachedStructInfo.AddField(structField, append(copyFieldIndexes, i), priorityTagArray)
}
cf.parseStructToCachedStructInfo(fieldType, append(copyFieldIndexes, i), cachedStructInfo, priorityTagArray)
continue
}
// Do not directly use append(fieldIndexes, i)
// When the structure is nested deeply, it may lead to bugs,
// which are caused by the slice expansion mechanism
// So it is necessary to allocate a separate index for each field
// See details https://github.com/gogf/gf/issues/3789
cachedStructInfo.AddField(structField, append(copyFieldIndexes, i), priorityTagArray)
}
}