mirror of
https://gitee.com/johng/gf
synced 2026-06-07 10:22: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.
252 lines
6.2 KiB
Go
252 lines
6.2 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 gring provides a concurrent-safe/unsafe ring(circular lists).
|
|
//
|
|
// Deprecated.
|
|
package gring
|
|
|
|
import (
|
|
"container/ring"
|
|
|
|
"github.com/gogf/gf/v2/container/gtype"
|
|
"github.com/gogf/gf/v2/internal/rwmutex"
|
|
)
|
|
|
|
// Ring is a struct of ring structure.
|
|
//
|
|
// Deprecated.
|
|
type Ring struct {
|
|
mu *rwmutex.RWMutex
|
|
ring *ring.Ring // Underlying ring.
|
|
len *gtype.Int // Length(already used size).
|
|
cap *gtype.Int // Capability(>=len).
|
|
dirty *gtype.Bool // Dirty, which means the len and cap should be recalculated. It's marked dirty when the size of ring changes.
|
|
}
|
|
|
|
// internalRingItem stores the ring element value.
|
|
type internalRingItem struct {
|
|
Value any
|
|
}
|
|
|
|
// New creates and returns a Ring structure of `cap` elements.
|
|
// The optional parameter `safe` specifies whether using this structure in concurrent safety,
|
|
// which is false in default.
|
|
//
|
|
// Deprecated.
|
|
func New(cap int, safe ...bool) *Ring {
|
|
return &Ring{
|
|
mu: rwmutex.New(safe...),
|
|
ring: ring.New(cap),
|
|
len: gtype.NewInt(),
|
|
cap: gtype.NewInt(cap),
|
|
dirty: gtype.NewBool(),
|
|
}
|
|
}
|
|
|
|
// Val returns the item's value of current position.
|
|
func (r *Ring) Val() any {
|
|
var value any
|
|
r.mu.RLock()
|
|
if r.ring.Value != nil {
|
|
value = r.ring.Value.(internalRingItem).Value
|
|
}
|
|
r.mu.RUnlock()
|
|
return value
|
|
}
|
|
|
|
// Len returns the size of ring.
|
|
func (r *Ring) Len() int {
|
|
r.checkAndUpdateLenAndCap()
|
|
return r.len.Val()
|
|
}
|
|
|
|
// Cap returns the capacity of ring.
|
|
func (r *Ring) Cap() int {
|
|
r.checkAndUpdateLenAndCap()
|
|
return r.cap.Val()
|
|
}
|
|
|
|
// Checks and updates the len and cap of ring when ring is dirty.
|
|
func (r *Ring) checkAndUpdateLenAndCap() {
|
|
if !r.dirty.Val() {
|
|
return
|
|
}
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
totalLen := 0
|
|
emptyLen := 0
|
|
if r.ring != nil {
|
|
if r.ring.Value == nil {
|
|
emptyLen++
|
|
}
|
|
totalLen++
|
|
for p := r.ring.Next(); p != r.ring; p = p.Next() {
|
|
if p.Value == nil {
|
|
emptyLen++
|
|
}
|
|
totalLen++
|
|
}
|
|
}
|
|
r.cap.Set(totalLen)
|
|
r.len.Set(totalLen - emptyLen)
|
|
r.dirty.Set(false)
|
|
}
|
|
|
|
// Set sets value to the item of current position.
|
|
func (r *Ring) Set(value any) *Ring {
|
|
r.mu.Lock()
|
|
if r.ring.Value == nil {
|
|
r.len.Add(1)
|
|
}
|
|
r.ring.Value = internalRingItem{Value: value}
|
|
r.mu.Unlock()
|
|
return r
|
|
}
|
|
|
|
// Put sets `value` to current item of ring and moves position to next item.
|
|
func (r *Ring) Put(value any) *Ring {
|
|
r.mu.Lock()
|
|
if r.ring.Value == nil {
|
|
r.len.Add(1)
|
|
}
|
|
r.ring.Value = internalRingItem{Value: value}
|
|
r.ring = r.ring.Next()
|
|
r.mu.Unlock()
|
|
return r
|
|
}
|
|
|
|
// Move moves n % r.Len() elements backward (n < 0) or forward (n >= 0)
|
|
// in the ring and returns that ring element. r must not be empty.
|
|
func (r *Ring) Move(n int) *Ring {
|
|
r.mu.Lock()
|
|
r.ring = r.ring.Move(n)
|
|
r.mu.Unlock()
|
|
return r
|
|
}
|
|
|
|
// Prev returns the previous ring element. r must not be empty.
|
|
func (r *Ring) Prev() *Ring {
|
|
r.mu.Lock()
|
|
r.ring = r.ring.Prev()
|
|
r.mu.Unlock()
|
|
return r
|
|
}
|
|
|
|
// Next returns the next ring element. r must not be empty.
|
|
func (r *Ring) Next() *Ring {
|
|
r.mu.Lock()
|
|
r.ring = r.ring.Next()
|
|
r.mu.Unlock()
|
|
return r
|
|
}
|
|
|
|
// Link connects ring r with ring s such that r.Next()
|
|
// becomes s and returns the original value for r.Next().
|
|
// r must not be empty.
|
|
//
|
|
// If r and s point to the same ring, linking
|
|
// them removes the elements between r and s from the ring.
|
|
// The removed elements form a sub-ring and the result is a
|
|
// reference to that sub-ring (if no elements were removed,
|
|
// the result is still the original value for r.Next(),
|
|
// and not nil).
|
|
//
|
|
// If r and s point to different rings, linking
|
|
// them creates a single ring with the elements of s inserted
|
|
// after r. The result points to the element following the
|
|
// last element of s after insertion.
|
|
func (r *Ring) Link(s *Ring) *Ring {
|
|
r.mu.Lock()
|
|
s.mu.Lock()
|
|
r.ring.Link(s.ring)
|
|
s.mu.Unlock()
|
|
r.mu.Unlock()
|
|
r.dirty.Set(true)
|
|
s.dirty.Set(true)
|
|
return r
|
|
}
|
|
|
|
// Unlink removes n % r.Len() elements from the ring r, starting
|
|
// at r.Next(). If n % r.Len() == 0, r remains unchanged.
|
|
// The result is the removed sub-ring. r must not be empty.
|
|
func (r *Ring) Unlink(n int) *Ring {
|
|
r.mu.Lock()
|
|
resultRing := r.ring.Unlink(n)
|
|
r.dirty.Set(true)
|
|
r.mu.Unlock()
|
|
resultGRing := New(resultRing.Len())
|
|
resultGRing.ring = resultRing
|
|
resultGRing.dirty.Set(true)
|
|
return resultGRing
|
|
}
|
|
|
|
// RLockIteratorNext iterates and locks reading forward
|
|
// with given callback function `f` within RWMutex.RLock.
|
|
// If `f` returns true, then it continues iterating; or false to stop.
|
|
func (r *Ring) RLockIteratorNext(f func(value any) bool) {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
if r.ring.Value != nil && !f(r.ring.Value.(internalRingItem).Value) {
|
|
return
|
|
}
|
|
for p := r.ring.Next(); p != r.ring; p = p.Next() {
|
|
if p.Value == nil || !f(p.Value.(internalRingItem).Value) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
// RLockIteratorPrev iterates and locks writing backward
|
|
// with given callback function `f` within RWMutex.RLock.
|
|
// If `f` returns true, then it continues iterating; or false to stop.
|
|
func (r *Ring) RLockIteratorPrev(f func(value any) bool) {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
if r.ring.Value != nil && !f(r.ring.Value.(internalRingItem).Value) {
|
|
return
|
|
}
|
|
for p := r.ring.Prev(); p != r.ring; p = p.Prev() {
|
|
if p.Value == nil || !f(p.Value.(internalRingItem).Value) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
// SliceNext returns a copy of all item values as slice forward from current position.
|
|
func (r *Ring) SliceNext() []any {
|
|
s := make([]any, 0)
|
|
r.mu.RLock()
|
|
if r.ring.Value != nil {
|
|
s = append(s, r.ring.Value.(internalRingItem).Value)
|
|
}
|
|
for p := r.ring.Next(); p != r.ring; p = p.Next() {
|
|
if p.Value == nil {
|
|
break
|
|
}
|
|
s = append(s, p.Value.(internalRingItem).Value)
|
|
}
|
|
r.mu.RUnlock()
|
|
return s
|
|
}
|
|
|
|
// SlicePrev returns a copy of all item values as slice backward from current position.
|
|
func (r *Ring) SlicePrev() []any {
|
|
s := make([]any, 0)
|
|
r.mu.RLock()
|
|
if r.ring.Value != nil {
|
|
s = append(s, r.ring.Value.(internalRingItem).Value)
|
|
}
|
|
for p := r.ring.Prev(); p != r.ring; p = p.Prev() {
|
|
if p.Value == nil {
|
|
break
|
|
}
|
|
s = append(s, p.Value.(internalRingItem).Value)
|
|
}
|
|
r.mu.RUnlock()
|
|
return s
|
|
}
|