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.
244 lines
5.1 KiB
Go
244 lines
5.1 KiB
Go
// Copyright GoFrame gf 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 empty provides functions for checking empty/nil variables.
|
|
package empty
|
|
|
|
import (
|
|
"reflect"
|
|
"time"
|
|
|
|
"github.com/gogf/gf/v2/internal/reflection"
|
|
)
|
|
|
|
// iString is used for type assert api for String().
|
|
type iString interface {
|
|
String() string
|
|
}
|
|
|
|
// iInterfaces is used for type assert api for Interfaces.
|
|
type iInterfaces interface {
|
|
Interfaces() []any
|
|
}
|
|
|
|
// iMapStrAny is the interface support for converting struct parameter to map.
|
|
type iMapStrAny interface {
|
|
MapStrAny() map[string]any
|
|
}
|
|
|
|
type iTime interface {
|
|
Date() (year int, month time.Month, day int)
|
|
IsZero() bool
|
|
}
|
|
|
|
// IsEmpty checks whether given `value` empty.
|
|
// It returns true if `value` is in: 0, nil, false, "", len(slice/map/chan) == 0,
|
|
// or else it returns false.
|
|
//
|
|
// The parameter `traceSource` is used for tracing to the source variable if given `value` is type of pointer
|
|
// that also points to a pointer. It returns true if the source is empty when `traceSource` is true.
|
|
// Note that it might use reflect feature which affects performance a little.
|
|
func IsEmpty(value any, traceSource ...bool) bool {
|
|
if value == nil {
|
|
return true
|
|
}
|
|
// It firstly checks the variable as common types using assertion to enhance the performance,
|
|
// and then using reflection.
|
|
switch result := value.(type) {
|
|
case int:
|
|
return result == 0
|
|
case int8:
|
|
return result == 0
|
|
case int16:
|
|
return result == 0
|
|
case int32:
|
|
return result == 0
|
|
case int64:
|
|
return result == 0
|
|
case uint:
|
|
return result == 0
|
|
case uint8:
|
|
return result == 0
|
|
case uint16:
|
|
return result == 0
|
|
case uint32:
|
|
return result == 0
|
|
case uint64:
|
|
return result == 0
|
|
case float32:
|
|
return result == 0
|
|
case float64:
|
|
return result == 0
|
|
case bool:
|
|
return !result
|
|
case string:
|
|
return result == ""
|
|
case []byte:
|
|
return len(result) == 0
|
|
case []rune:
|
|
return len(result) == 0
|
|
case []int:
|
|
return len(result) == 0
|
|
case []string:
|
|
return len(result) == 0
|
|
case []float32:
|
|
return len(result) == 0
|
|
case []float64:
|
|
return len(result) == 0
|
|
case map[string]any:
|
|
return len(result) == 0
|
|
|
|
default:
|
|
// Finally, using reflect.
|
|
var rv reflect.Value
|
|
if v, ok := value.(reflect.Value); ok {
|
|
rv = v
|
|
} else {
|
|
rv = reflect.ValueOf(value)
|
|
if IsNil(rv) {
|
|
return true
|
|
}
|
|
|
|
// =========================
|
|
// Common interfaces checks.
|
|
// =========================
|
|
if f, ok := value.(iTime); ok {
|
|
if f == (*time.Time)(nil) {
|
|
return true
|
|
}
|
|
return f.IsZero()
|
|
}
|
|
if f, ok := value.(iString); ok {
|
|
if f == nil {
|
|
return true
|
|
}
|
|
return f.String() == ""
|
|
}
|
|
if f, ok := value.(iInterfaces); ok {
|
|
if f == nil {
|
|
return true
|
|
}
|
|
return len(f.Interfaces()) == 0
|
|
}
|
|
if f, ok := value.(iMapStrAny); ok {
|
|
if f == nil {
|
|
return true
|
|
}
|
|
return len(f.MapStrAny()) == 0
|
|
}
|
|
}
|
|
|
|
switch rv.Kind() {
|
|
case reflect.Bool:
|
|
return !rv.Bool()
|
|
|
|
case
|
|
reflect.Int,
|
|
reflect.Int8,
|
|
reflect.Int16,
|
|
reflect.Int32,
|
|
reflect.Int64:
|
|
return rv.Int() == 0
|
|
|
|
case
|
|
reflect.Uint,
|
|
reflect.Uint8,
|
|
reflect.Uint16,
|
|
reflect.Uint32,
|
|
reflect.Uint64,
|
|
reflect.Uintptr:
|
|
return rv.Uint() == 0
|
|
|
|
case
|
|
reflect.Float32,
|
|
reflect.Float64:
|
|
return rv.Float() == 0
|
|
|
|
case reflect.String:
|
|
return rv.Len() == 0
|
|
|
|
case reflect.Struct:
|
|
var fieldValueInterface any
|
|
for i := 0; i < rv.NumField(); i++ {
|
|
fieldValueInterface, _ = reflection.ValueToInterface(rv.Field(i))
|
|
if !IsEmpty(fieldValueInterface) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
|
|
case
|
|
reflect.Chan,
|
|
reflect.Map,
|
|
reflect.Slice,
|
|
reflect.Array:
|
|
return rv.Len() == 0
|
|
|
|
case reflect.Pointer:
|
|
if len(traceSource) > 0 && traceSource[0] {
|
|
return IsEmpty(rv.Elem())
|
|
}
|
|
return rv.IsNil()
|
|
|
|
case
|
|
reflect.Func,
|
|
reflect.Interface,
|
|
reflect.UnsafePointer:
|
|
return rv.IsNil()
|
|
|
|
case reflect.Invalid:
|
|
return true
|
|
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
|
|
// IsNil checks whether given `value` is nil, especially for any type value.
|
|
// Parameter `traceSource` is used for tracing to the source variable if given `value` is type of pointer
|
|
// that also points to a pointer. It returns nil if the source is nil when `traceSource` is true.
|
|
// Note that it might use reflect feature which affects performance a little.
|
|
func IsNil(value any, traceSource ...bool) bool {
|
|
if value == nil {
|
|
return true
|
|
}
|
|
var rv reflect.Value
|
|
if v, ok := value.(reflect.Value); ok {
|
|
rv = v
|
|
} else {
|
|
rv = reflect.ValueOf(value)
|
|
}
|
|
switch rv.Kind() {
|
|
case reflect.Chan,
|
|
reflect.Map,
|
|
reflect.Slice,
|
|
reflect.Func,
|
|
reflect.Interface,
|
|
reflect.UnsafePointer:
|
|
return !rv.IsValid() || rv.IsNil()
|
|
|
|
case reflect.Pointer:
|
|
if len(traceSource) > 0 && traceSource[0] {
|
|
for rv.Kind() == reflect.Pointer {
|
|
rv = rv.Elem()
|
|
}
|
|
if !rv.IsValid() {
|
|
return true
|
|
}
|
|
if rv.Kind() == reflect.Pointer {
|
|
return rv.IsNil()
|
|
}
|
|
} else {
|
|
return !rv.IsValid() || rv.IsNil()
|
|
}
|
|
|
|
default:
|
|
return false
|
|
}
|
|
return false
|
|
}
|