mirror of
https://gitee.com/johng/gf
synced 2026-06-07 02:12:11 +08:00
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.
149 lines
5.0 KiB
Go
149 lines
5.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"
|
|
"sync/atomic"
|
|
)
|
|
|
|
// CachedFieldInfo holds the cached info for struct field.
|
|
type CachedFieldInfo struct {
|
|
// WARN:
|
|
// The [CachedFieldInfoBase] structure cannot be merged with the following [IsField] field into one structure.
|
|
// The [IsField] field should be used separately in the [bindStructWithLoopParamsMap] method
|
|
*CachedFieldInfoBase
|
|
|
|
// This field is mainly used in the [bindStructWithLoopParamsMap] method.
|
|
// This field is needed when both `fieldName` and `tag` of a field exist in the map.
|
|
// For example:
|
|
// field string `json:"name"`
|
|
// map = {
|
|
// "field" : "f1",
|
|
// "name" : "n1",
|
|
// }
|
|
// The `name` should be used here.
|
|
// In the bindStructWithLoopParamsMap method, due to the disorder of `map`, `field` may be traversed first.
|
|
// This field is more about priority, that is, the priority of `name` is higher than that of `field`,
|
|
// even if it has been set before.
|
|
IsField bool
|
|
}
|
|
|
|
// CachedFieldInfoBase holds the cached info for struct field.
|
|
type CachedFieldInfoBase struct {
|
|
// FieldIndexes holds the global index number from struct info.
|
|
// The field may belong to an embedded structure, so it is defined here as []int.
|
|
FieldIndexes []int
|
|
|
|
// PriorityTagAndFieldName holds the tag value(conv, param, p, c, json) and the field name.
|
|
// PriorityTagAndFieldName contains the field name, which is the last item of slice.
|
|
PriorityTagAndFieldName []string
|
|
|
|
// IsCommonInterface marks this field implements common interfaces as:
|
|
// - iUnmarshalValue
|
|
// - iUnmarshalText
|
|
// - iUnmarshalJSON
|
|
// Purpose: reduce the interface asserting cost in runtime.
|
|
IsCommonInterface bool
|
|
|
|
// HasCustomConvert marks there custom converting function for this field type.
|
|
// A custom converting function is a function that user defined for converting specified type
|
|
// to another type.
|
|
HasCustomConvert bool
|
|
|
|
// StructField is the type info of this field.
|
|
StructField reflect.StructField
|
|
|
|
// OtherSameNameField stores fields with the same name and type or different types of nested structures.
|
|
//
|
|
// For example:
|
|
// type ID struct{
|
|
// ID1 string
|
|
// ID2 int
|
|
// }
|
|
// type Card struct{
|
|
// ID
|
|
// ID1 uint64
|
|
// ID2 int64
|
|
// }
|
|
//
|
|
// We will cache each ID1 and ID2 separately,
|
|
// even if their types are different and their indexes are different
|
|
OtherSameNameField []*CachedFieldInfo
|
|
|
|
// ConvertFunc is the converting function for this field.
|
|
ConvertFunc AnyConvertFunc
|
|
|
|
// The last fuzzy matching key for this field.
|
|
// The fuzzy matching occurs only if there are no direct tag and field name matching in the params map.
|
|
// TODO If different paramsMaps contain paramKeys in different formats and all hit the same fieldName,
|
|
// the cached value may be continuously updated.
|
|
// LastFuzzyKey string.
|
|
LastFuzzyKey atomic.Value
|
|
|
|
// removeSymbolsFieldName is used for quick fuzzy match for parameter key.
|
|
// removeSymbolsFieldName = utils.RemoveSymbols(fieldName)
|
|
RemoveSymbolsFieldName string
|
|
}
|
|
|
|
// FieldName returns the field name of current field info.
|
|
func (cfi *CachedFieldInfo) FieldName() string {
|
|
return cfi.PriorityTagAndFieldName[len(cfi.PriorityTagAndFieldName)-1]
|
|
}
|
|
|
|
// GetFieldReflectValueFrom retrieves and returns the `reflect.Value` of given struct field,
|
|
// which is used for directly value assignment.
|
|
//
|
|
// Note that, the input parameter `structValue` might be initialized internally.
|
|
func (cfi *CachedFieldInfo) GetFieldReflectValueFrom(structValue reflect.Value) reflect.Value {
|
|
if len(cfi.FieldIndexes) == 1 {
|
|
// no nested struct.
|
|
return structValue.Field(cfi.FieldIndexes[0])
|
|
}
|
|
return cfi.fieldReflectValue(structValue, cfi.FieldIndexes)
|
|
}
|
|
|
|
// GetOtherFieldReflectValueFrom retrieves and returns the `reflect.Value` of given struct field with nested index
|
|
// by `fieldLevel`, which is used for directly value assignment.
|
|
//
|
|
// Note that, the input parameter `structValue` might be initialized internally.
|
|
func (cfi *CachedFieldInfo) GetOtherFieldReflectValueFrom(structValue reflect.Value, fieldIndex []int) reflect.Value {
|
|
if len(fieldIndex) == 1 {
|
|
// no nested struct.
|
|
return structValue.Field(fieldIndex[0])
|
|
}
|
|
return cfi.fieldReflectValue(structValue, fieldIndex)
|
|
}
|
|
|
|
func (cfi *CachedFieldInfo) fieldReflectValue(v reflect.Value, fieldIndexes []int) reflect.Value {
|
|
for i, x := range fieldIndexes {
|
|
if i > 0 {
|
|
// it means nested struct.
|
|
switch v.Kind() {
|
|
case reflect.Pointer:
|
|
if v.IsNil() {
|
|
// Initialization.
|
|
v.Set(reflect.New(v.Type().Elem()))
|
|
}
|
|
v = v.Elem()
|
|
|
|
case reflect.Interface:
|
|
// Compatible with previous code
|
|
// Interface => struct
|
|
v = v.Elem()
|
|
if v.Kind() == reflect.Pointer {
|
|
// maybe *struct or other types
|
|
v = v.Elem()
|
|
}
|
|
default:
|
|
}
|
|
}
|
|
v = v.Field(x)
|
|
}
|
|
return v
|
|
}
|