mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +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.
574 lines
13 KiB
Go
574 lines
13 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 l file,
|
|
// You can obtain one at https://github.com/gogf/gf.
|
|
//
|
|
|
|
// Package glist provides most commonly used doubly linked list container which also supports
|
|
// concurrent-safe/unsafe switch feature.
|
|
package glist
|
|
|
|
import (
|
|
"bytes"
|
|
"container/list"
|
|
|
|
"github.com/gogf/gf/v2/internal/deepcopy"
|
|
"github.com/gogf/gf/v2/internal/json"
|
|
"github.com/gogf/gf/v2/internal/rwmutex"
|
|
"github.com/gogf/gf/v2/util/gconv"
|
|
)
|
|
|
|
type (
|
|
// List is a doubly linked list containing a concurrent-safe/unsafe switch.
|
|
// The switch should be set when its initialization and cannot be changed then.
|
|
List struct {
|
|
mu rwmutex.RWMutex
|
|
list *list.List
|
|
}
|
|
// Element the item type of the list.
|
|
Element = list.Element
|
|
)
|
|
|
|
// New creates and returns a new empty doubly linked list.
|
|
func New(safe ...bool) *List {
|
|
return &List{
|
|
mu: rwmutex.Create(safe...),
|
|
list: list.New(),
|
|
}
|
|
}
|
|
|
|
// NewFrom creates and returns a list from a copy of given slice `array`.
|
|
// The parameter `safe` is used to specify whether using list in concurrent-safety,
|
|
// which is false in default.
|
|
func NewFrom(array []any, safe ...bool) *List {
|
|
l := list.New()
|
|
for _, v := range array {
|
|
l.PushBack(v)
|
|
}
|
|
return &List{
|
|
mu: rwmutex.Create(safe...),
|
|
list: l,
|
|
}
|
|
}
|
|
|
|
// PushFront inserts a new element `e` with value `v` at the front of list `l` and returns `e`.
|
|
func (l *List) PushFront(v any) (e *Element) {
|
|
l.mu.Lock()
|
|
if l.list == nil {
|
|
l.list = list.New()
|
|
}
|
|
e = l.list.PushFront(v)
|
|
l.mu.Unlock()
|
|
return
|
|
}
|
|
|
|
// PushBack inserts a new element `e` with value `v` at the back of list `l` and returns `e`.
|
|
func (l *List) PushBack(v any) (e *Element) {
|
|
l.mu.Lock()
|
|
if l.list == nil {
|
|
l.list = list.New()
|
|
}
|
|
e = l.list.PushBack(v)
|
|
l.mu.Unlock()
|
|
return
|
|
}
|
|
|
|
// PushFronts inserts multiple new elements with values `values` at the front of list `l`.
|
|
func (l *List) PushFronts(values []any) {
|
|
l.mu.Lock()
|
|
if l.list == nil {
|
|
l.list = list.New()
|
|
}
|
|
for _, v := range values {
|
|
l.list.PushFront(v)
|
|
}
|
|
l.mu.Unlock()
|
|
}
|
|
|
|
// PushBacks inserts multiple new elements with values `values` at the back of list `l`.
|
|
func (l *List) PushBacks(values []any) {
|
|
l.mu.Lock()
|
|
if l.list == nil {
|
|
l.list = list.New()
|
|
}
|
|
for _, v := range values {
|
|
l.list.PushBack(v)
|
|
}
|
|
l.mu.Unlock()
|
|
}
|
|
|
|
// PopBack removes the element from back of `l` and returns the value of the element.
|
|
func (l *List) PopBack() (value any) {
|
|
l.mu.Lock()
|
|
defer l.mu.Unlock()
|
|
if l.list == nil {
|
|
l.list = list.New()
|
|
return
|
|
}
|
|
if e := l.list.Back(); e != nil {
|
|
value = l.list.Remove(e)
|
|
}
|
|
return
|
|
}
|
|
|
|
// PopFront removes the element from front of `l` and returns the value of the element.
|
|
func (l *List) PopFront() (value any) {
|
|
l.mu.Lock()
|
|
defer l.mu.Unlock()
|
|
if l.list == nil {
|
|
l.list = list.New()
|
|
return
|
|
}
|
|
if e := l.list.Front(); e != nil {
|
|
value = l.list.Remove(e)
|
|
}
|
|
return
|
|
}
|
|
|
|
// PopBacks removes `max` elements from back of `l`
|
|
// and returns values of the removed elements as slice.
|
|
func (l *List) PopBacks(max int) (values []any) {
|
|
l.mu.Lock()
|
|
defer l.mu.Unlock()
|
|
if l.list == nil {
|
|
l.list = list.New()
|
|
return
|
|
}
|
|
length := l.list.Len()
|
|
if length > 0 {
|
|
if max > 0 && max < length {
|
|
length = max
|
|
}
|
|
values = make([]any, length)
|
|
for i := 0; i < length; i++ {
|
|
values[i] = l.list.Remove(l.list.Back())
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// PopFronts removes `max` elements from front of `l`
|
|
// and returns values of the removed elements as slice.
|
|
func (l *List) PopFronts(max int) (values []any) {
|
|
l.mu.Lock()
|
|
defer l.mu.Unlock()
|
|
if l.list == nil {
|
|
l.list = list.New()
|
|
return
|
|
}
|
|
length := l.list.Len()
|
|
if length > 0 {
|
|
if max > 0 && max < length {
|
|
length = max
|
|
}
|
|
values = make([]any, length)
|
|
for i := 0; i < length; i++ {
|
|
values[i] = l.list.Remove(l.list.Front())
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// PopBackAll removes all elements from back of `l`
|
|
// and returns values of the removed elements as slice.
|
|
func (l *List) PopBackAll() []any {
|
|
return l.PopBacks(-1)
|
|
}
|
|
|
|
// PopFrontAll removes all elements from front of `l`
|
|
// and returns values of the removed elements as slice.
|
|
func (l *List) PopFrontAll() []any {
|
|
return l.PopFronts(-1)
|
|
}
|
|
|
|
// FrontAll copies and returns values of all elements from front of `l` as slice.
|
|
func (l *List) FrontAll() (values []any) {
|
|
l.mu.RLock()
|
|
defer l.mu.RUnlock()
|
|
if l.list == nil {
|
|
return
|
|
}
|
|
length := l.list.Len()
|
|
if length > 0 {
|
|
values = make([]any, length)
|
|
for i, e := 0, l.list.Front(); i < length; i, e = i+1, e.Next() {
|
|
values[i] = e.Value
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// BackAll copies and returns values of all elements from back of `l` as slice.
|
|
func (l *List) BackAll() (values []any) {
|
|
l.mu.RLock()
|
|
defer l.mu.RUnlock()
|
|
if l.list == nil {
|
|
return
|
|
}
|
|
length := l.list.Len()
|
|
if length > 0 {
|
|
values = make([]any, length)
|
|
for i, e := 0, l.list.Back(); i < length; i, e = i+1, e.Prev() {
|
|
values[i] = e.Value
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// FrontValue returns value of the first element of `l` or nil if the list is empty.
|
|
func (l *List) FrontValue() (value any) {
|
|
l.mu.RLock()
|
|
defer l.mu.RUnlock()
|
|
if l.list == nil {
|
|
return
|
|
}
|
|
if e := l.list.Front(); e != nil {
|
|
value = e.Value
|
|
}
|
|
return
|
|
}
|
|
|
|
// BackValue returns value of the last element of `l` or nil if the list is empty.
|
|
func (l *List) BackValue() (value any) {
|
|
l.mu.RLock()
|
|
defer l.mu.RUnlock()
|
|
if l.list == nil {
|
|
return
|
|
}
|
|
if e := l.list.Back(); e != nil {
|
|
value = e.Value
|
|
}
|
|
return
|
|
}
|
|
|
|
// Front returns the first element of list `l` or nil if the list is empty.
|
|
func (l *List) Front() (e *Element) {
|
|
l.mu.RLock()
|
|
defer l.mu.RUnlock()
|
|
if l.list == nil {
|
|
return
|
|
}
|
|
e = l.list.Front()
|
|
return
|
|
}
|
|
|
|
// Back returns the last element of list `l` or nil if the list is empty.
|
|
func (l *List) Back() (e *Element) {
|
|
l.mu.RLock()
|
|
defer l.mu.RUnlock()
|
|
if l.list == nil {
|
|
return
|
|
}
|
|
e = l.list.Back()
|
|
return
|
|
}
|
|
|
|
// Len returns the number of elements of list `l`.
|
|
// The complexity is O(1).
|
|
func (l *List) Len() (length int) {
|
|
l.mu.RLock()
|
|
defer l.mu.RUnlock()
|
|
if l.list == nil {
|
|
return
|
|
}
|
|
length = l.list.Len()
|
|
return
|
|
}
|
|
|
|
// Size is alias of Len.
|
|
func (l *List) Size() int {
|
|
return l.Len()
|
|
}
|
|
|
|
// MoveBefore moves element `e` to its new position before `p`.
|
|
// If `e` or `p` is not an element of `l`, or `e` == `p`, the list is not modified.
|
|
// The element and `p` must not be nil.
|
|
func (l *List) MoveBefore(e, p *Element) {
|
|
l.mu.Lock()
|
|
defer l.mu.Unlock()
|
|
if l.list == nil {
|
|
l.list = list.New()
|
|
}
|
|
l.list.MoveBefore(e, p)
|
|
}
|
|
|
|
// MoveAfter moves element `e` to its new position after `p`.
|
|
// If `e` or `p` is not an element of `l`, or `e` == `p`, the list is not modified.
|
|
// The element and `p` must not be nil.
|
|
func (l *List) MoveAfter(e, p *Element) {
|
|
l.mu.Lock()
|
|
defer l.mu.Unlock()
|
|
if l.list == nil {
|
|
l.list = list.New()
|
|
}
|
|
l.list.MoveAfter(e, p)
|
|
}
|
|
|
|
// MoveToFront moves element `e` to the front of list `l`.
|
|
// If `e` is not an element of `l`, the list is not modified.
|
|
// The element must not be nil.
|
|
func (l *List) MoveToFront(e *Element) {
|
|
l.mu.Lock()
|
|
defer l.mu.Unlock()
|
|
if l.list == nil {
|
|
l.list = list.New()
|
|
}
|
|
l.list.MoveToFront(e)
|
|
}
|
|
|
|
// MoveToBack moves element `e` to the back of list `l`.
|
|
// If `e` is not an element of `l`, the list is not modified.
|
|
// The element must not be nil.
|
|
func (l *List) MoveToBack(e *Element) {
|
|
l.mu.Lock()
|
|
defer l.mu.Unlock()
|
|
if l.list == nil {
|
|
l.list = list.New()
|
|
}
|
|
l.list.MoveToBack(e)
|
|
}
|
|
|
|
// PushBackList inserts a copy of an other list at the back of list `l`.
|
|
// The lists `l` and `other` may be the same, but they must not be nil.
|
|
func (l *List) PushBackList(other *List) {
|
|
if l != other {
|
|
other.mu.RLock()
|
|
defer other.mu.RUnlock()
|
|
}
|
|
l.mu.Lock()
|
|
defer l.mu.Unlock()
|
|
if l.list == nil {
|
|
l.list = list.New()
|
|
}
|
|
l.list.PushBackList(other.list)
|
|
}
|
|
|
|
// PushFrontList inserts a copy of an other list at the front of list `l`.
|
|
// The lists `l` and `other` may be the same, but they must not be nil.
|
|
func (l *List) PushFrontList(other *List) {
|
|
if l != other {
|
|
other.mu.RLock()
|
|
defer other.mu.RUnlock()
|
|
}
|
|
l.mu.Lock()
|
|
defer l.mu.Unlock()
|
|
if l.list == nil {
|
|
l.list = list.New()
|
|
}
|
|
l.list.PushFrontList(other.list)
|
|
}
|
|
|
|
// InsertAfter inserts a new element `e` with value `v` immediately after `p` and returns `e`.
|
|
// If `p` is not an element of `l`, the list is not modified.
|
|
// The `p` must not be nil.
|
|
func (l *List) InsertAfter(p *Element, v any) (e *Element) {
|
|
l.mu.Lock()
|
|
defer l.mu.Unlock()
|
|
if l.list == nil {
|
|
l.list = list.New()
|
|
}
|
|
e = l.list.InsertAfter(v, p)
|
|
return
|
|
}
|
|
|
|
// InsertBefore inserts a new element `e` with value `v` immediately before `p` and returns `e`.
|
|
// If `p` is not an element of `l`, the list is not modified.
|
|
// The `p` must not be nil.
|
|
func (l *List) InsertBefore(p *Element, v any) (e *Element) {
|
|
l.mu.Lock()
|
|
defer l.mu.Unlock()
|
|
if l.list == nil {
|
|
l.list = list.New()
|
|
}
|
|
e = l.list.InsertBefore(v, p)
|
|
return
|
|
}
|
|
|
|
// Remove removes `e` from `l` if `e` is an element of list `l`.
|
|
// It returns the element value e.Value.
|
|
// The element must not be nil.
|
|
func (l *List) Remove(e *Element) (value any) {
|
|
l.mu.Lock()
|
|
defer l.mu.Unlock()
|
|
if l.list == nil {
|
|
l.list = list.New()
|
|
}
|
|
value = l.list.Remove(e)
|
|
return
|
|
}
|
|
|
|
// Removes removes multiple elements `es` from `l` if `es` are elements of list `l`.
|
|
func (l *List) Removes(es []*Element) {
|
|
l.mu.Lock()
|
|
defer l.mu.Unlock()
|
|
if l.list == nil {
|
|
l.list = list.New()
|
|
}
|
|
for _, e := range es {
|
|
l.list.Remove(e)
|
|
}
|
|
}
|
|
|
|
// RemoveAll removes all elements from list `l`.
|
|
func (l *List) RemoveAll() {
|
|
l.mu.Lock()
|
|
l.list = list.New()
|
|
l.mu.Unlock()
|
|
}
|
|
|
|
// Clear is alias of RemoveAll.
|
|
func (l *List) Clear() {
|
|
l.RemoveAll()
|
|
}
|
|
|
|
// RLockFunc locks reading with given callback function `f` within RWMutex.RLock.
|
|
func (l *List) RLockFunc(f func(list *list.List)) {
|
|
l.mu.RLock()
|
|
defer l.mu.RUnlock()
|
|
if l.list != nil {
|
|
f(l.list)
|
|
}
|
|
}
|
|
|
|
// LockFunc locks writing with given callback function `f` within RWMutex.Lock.
|
|
func (l *List) LockFunc(f func(list *list.List)) {
|
|
l.mu.Lock()
|
|
defer l.mu.Unlock()
|
|
if l.list == nil {
|
|
l.list = list.New()
|
|
}
|
|
f(l.list)
|
|
}
|
|
|
|
// Iterator is alias of IteratorAsc.
|
|
func (l *List) Iterator(f func(e *Element) bool) {
|
|
l.IteratorAsc(f)
|
|
}
|
|
|
|
// IteratorAsc iterates the list readonly in ascending order with given callback function `f`.
|
|
// If `f` returns true, then it continues iterating; or false to stop.
|
|
func (l *List) IteratorAsc(f func(e *Element) bool) {
|
|
l.mu.RLock()
|
|
defer l.mu.RUnlock()
|
|
if l.list == nil {
|
|
return
|
|
}
|
|
length := l.list.Len()
|
|
if length > 0 {
|
|
for i, e := 0, l.list.Front(); i < length; i, e = i+1, e.Next() {
|
|
if !f(e) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// IteratorDesc iterates the list readonly in descending order with given callback function `f`.
|
|
// If `f` returns true, then it continues iterating; or false to stop.
|
|
func (l *List) IteratorDesc(f func(e *Element) bool) {
|
|
l.mu.RLock()
|
|
defer l.mu.RUnlock()
|
|
if l.list == nil {
|
|
return
|
|
}
|
|
length := l.list.Len()
|
|
if length > 0 {
|
|
for i, e := 0, l.list.Back(); i < length; i, e = i+1, e.Prev() {
|
|
if !f(e) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Join joins list elements with a string `glue`.
|
|
func (l *List) Join(glue string) string {
|
|
l.mu.RLock()
|
|
defer l.mu.RUnlock()
|
|
if l.list == nil {
|
|
return ""
|
|
}
|
|
buffer := bytes.NewBuffer(nil)
|
|
length := l.list.Len()
|
|
if length > 0 {
|
|
for i, e := 0, l.list.Front(); i < length; i, e = i+1, e.Next() {
|
|
buffer.WriteString(gconv.String(e.Value))
|
|
if i != length-1 {
|
|
buffer.WriteString(glue)
|
|
}
|
|
}
|
|
}
|
|
return buffer.String()
|
|
}
|
|
|
|
// String returns current list as a string.
|
|
func (l *List) String() string {
|
|
if l == nil {
|
|
return ""
|
|
}
|
|
return "[" + l.Join(",") + "]"
|
|
}
|
|
|
|
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
|
|
func (l List) MarshalJSON() ([]byte, error) {
|
|
return json.Marshal(l.FrontAll())
|
|
}
|
|
|
|
// UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
|
|
func (l *List) UnmarshalJSON(b []byte) error {
|
|
l.mu.Lock()
|
|
defer l.mu.Unlock()
|
|
if l.list == nil {
|
|
l.list = list.New()
|
|
}
|
|
var array []any
|
|
if err := json.UnmarshalUseNumber(b, &array); err != nil {
|
|
return err
|
|
}
|
|
l.PushBacks(array)
|
|
return nil
|
|
}
|
|
|
|
// UnmarshalValue is an interface implement which sets any type of value for list.
|
|
func (l *List) UnmarshalValue(value any) (err error) {
|
|
l.mu.Lock()
|
|
defer l.mu.Unlock()
|
|
if l.list == nil {
|
|
l.list = list.New()
|
|
}
|
|
var array []any
|
|
switch value.(type) {
|
|
case string, []byte:
|
|
err = json.UnmarshalUseNumber(gconv.Bytes(value), &array)
|
|
default:
|
|
array = gconv.SliceAny(value)
|
|
}
|
|
l.PushBacks(array)
|
|
return err
|
|
}
|
|
|
|
// DeepCopy implements interface for deep copy of current type.
|
|
func (l *List) DeepCopy() any {
|
|
if l == nil {
|
|
return nil
|
|
}
|
|
|
|
l.mu.RLock()
|
|
defer l.mu.RUnlock()
|
|
|
|
if l.list == nil {
|
|
return nil
|
|
}
|
|
var (
|
|
length = l.list.Len()
|
|
values = make([]any, length)
|
|
)
|
|
if length > 0 {
|
|
for i, e := 0, l.list.Front(); i < length; i, e = i+1, e.Next() {
|
|
values[i] = deepcopy.Copy(e.Value)
|
|
}
|
|
}
|
|
return NewFrom(values, l.mu.IsSafe())
|
|
}
|