diff --git a/container/garray/garray_normal_any.go b/container/garray/garray_normal_any.go index 616a59062..985c02fc7 100644 --- a/container/garray/garray_normal_any.go +++ b/container/garray/garray_normal_any.go @@ -30,7 +30,7 @@ type Array struct { } // New creates and returns an empty array. -// The parameter is used to specify whether using array in concurrent-safety, +// The parameter `safe` is used to specify whether using array in concurrent-safety, // which is false in default. func New(safe ...bool) *Array { return NewArraySize(0, 0, safe...) @@ -42,7 +42,7 @@ func NewArray(safe ...bool) *Array { } // NewArraySize create and returns an array with given size and cap. -// The parameter is used to specify whether using array in concurrent-safety, +// The parameter `safe` is used to specify whether using array in concurrent-safety, // which is false in default. func NewArraySize(size int, cap int, safe ...bool) *Array { return &Array{ @@ -51,8 +51,8 @@ func NewArraySize(size int, cap int, safe ...bool) *Array { } } -// NewArrayRange creates and returns a array by a range from to -// with step value . +// NewArrayRange creates and returns a array by a range from `start` to `end` +// with step value `step`. func NewArrayRange(start, end, step int, safe ...bool) *Array { if step == 0 { panic(fmt.Sprintf(`invalid step value: %d`, step)) @@ -66,18 +66,20 @@ func NewArrayRange(start, end, step int, safe ...bool) *Array { return NewArrayFrom(slice, safe...) } +// NewFrom is alias of NewArrayFrom. // See NewArrayFrom. func NewFrom(array []interface{}, safe ...bool) *Array { return NewArrayFrom(array, safe...) } +// NewFromCopy is alias of NewArrayFromCopy. // See NewArrayFromCopy. func NewFromCopy(array []interface{}, safe ...bool) *Array { return NewArrayFromCopy(array, safe...) } -// NewArrayFrom creates and returns an array with given slice . -// The parameter is used to specify whether using array in concurrent-safety, +// NewArrayFrom creates and returns an array with given slice `array`. +// The parameter `safe` is used to specify whether using array in concurrent-safety, // which is false in default. func NewArrayFrom(array []interface{}, safe ...bool) *Array { return &Array{ @@ -86,8 +88,8 @@ func NewArrayFrom(array []interface{}, safe ...bool) *Array { } } -// NewArrayFromCopy creates and returns an array from a copy of given slice . -// The parameter is used to specify whether using array in concurrent-safety, +// NewArrayFromCopy creates and returns an array from a copy of given slice `array`. +// The parameter `safe` is used to specify whether using array in concurrent-safety, // which is false in default. func NewArrayFromCopy(array []interface{}, safe ...bool) *Array { newArray := make([]interface{}, len(array)) @@ -98,8 +100,15 @@ func NewArrayFromCopy(array []interface{}, safe ...bool) *Array { } } +// At returns the value by the specified index. +// If the given `index` is out of range of the array, it returns `nil`. +func (a *Array) At(index int) (value interface{}) { + value, _ = a.Get(index) + return +} + // Get returns the value by the specified index. -// If the given is out of range of the array, the is false. +// If the given `index` is out of range of the array, the `found` is false. func (a *Array) Get(index int) (value interface{}, found bool) { a.mu.RLock() defer a.mu.RUnlock() @@ -120,7 +129,7 @@ func (a *Array) Set(index int, value interface{}) error { return nil } -// SetArray sets the underlying slice array with the given . +// SetArray sets the underlying slice array with the given `array`. func (a *Array) SetArray(array []interface{}) *Array { a.mu.Lock() defer a.mu.Unlock() @@ -128,7 +137,7 @@ func (a *Array) SetArray(array []interface{}) *Array { return a } -// Replace replaces the array items by given from the beginning of array. +// Replace replaces the array items by given `array` from the beginning of array. func (a *Array) Replace(array []interface{}) *Array { a.mu.Lock() defer a.mu.Unlock() @@ -152,7 +161,7 @@ func (a *Array) Sum() (sum int) { return } -// SortFunc sorts the array by custom function . +// SortFunc sorts the array by custom function `less`. func (a *Array) SortFunc(less func(v1, v2 interface{}) bool) *Array { a.mu.Lock() defer a.mu.Unlock() @@ -162,7 +171,7 @@ func (a *Array) SortFunc(less func(v1, v2 interface{}) bool) *Array { return a } -// InsertBefore inserts the to the front of . +// InsertBefore inserts the `value` to the front of `index`. func (a *Array) InsertBefore(index int, value interface{}) error { a.mu.Lock() defer a.mu.Unlock() @@ -175,7 +184,7 @@ func (a *Array) InsertBefore(index int, value interface{}) error { return nil } -// InsertAfter inserts the to the back of . +// InsertAfter inserts the `value` to the back of `index`. func (a *Array) InsertAfter(index int, value interface{}) error { a.mu.Lock() defer a.mu.Unlock() @@ -189,7 +198,7 @@ func (a *Array) InsertAfter(index int, value interface{}) error { } // Remove removes an item by index. -// If the given is out of range of the array, the is false. +// If the given `index` is out of range of the array, the `found` is false. func (a *Array) Remove(index int) (value interface{}, found bool) { a.mu.Lock() defer a.mu.Unlock() @@ -247,14 +256,14 @@ func (a *Array) PushRight(value ...interface{}) *Array { } // PopRand randomly pops and return an item out of array. -// Note that if the array is empty, the is false. +// Note that if the array is empty, the `found` is false. func (a *Array) PopRand() (value interface{}, found bool) { a.mu.Lock() defer a.mu.Unlock() return a.doRemoveWithoutLock(grand.Intn(len(a.array))) } -// PopRands randomly pops and returns items out of array. +// PopRands randomly pops and returns `size` items out of array. func (a *Array) PopRands(size int) []interface{} { a.mu.Lock() defer a.mu.Unlock() @@ -272,7 +281,7 @@ func (a *Array) PopRands(size int) []interface{} { } // PopLeft pops and returns an item from the beginning of array. -// Note that if the array is empty, the is false. +// Note that if the array is empty, the `found` is false. func (a *Array) PopLeft() (value interface{}, found bool) { a.mu.Lock() defer a.mu.Unlock() @@ -285,7 +294,7 @@ func (a *Array) PopLeft() (value interface{}, found bool) { } // PopRight pops and returns an item from the end of array. -// Note that if the array is empty, the is false. +// Note that if the array is empty, the `found` is false. func (a *Array) PopRight() (value interface{}, found bool) { a.mu.Lock() defer a.mu.Unlock() @@ -298,7 +307,7 @@ func (a *Array) PopRight() (value interface{}, found bool) { return value, true } -// PopLefts pops and returns items from the beginning of array. +// PopLefts pops and returns `size` items from the beginning of array. func (a *Array) PopLefts(size int) []interface{} { a.mu.Lock() defer a.mu.Unlock() @@ -315,7 +324,7 @@ func (a *Array) PopLefts(size int) []interface{} { return value } -// PopRights pops and returns items from the end of array. +// PopRights pops and returns `size` items from the end of array. func (a *Array) PopRights(size int) []interface{} { a.mu.Lock() defer a.mu.Unlock() @@ -337,8 +346,8 @@ func (a *Array) PopRights(size int) []interface{} { // Notice, if in concurrent-safe usage, it returns a copy of slice; // else a pointer to the underlying data. // -// If is negative, then the offset will start from the end of array. -// If is omitted, then the sequence will have everything from start up +// If `end` is negative, then the offset will start from the end of array. +// If `end` is omitted, then the sequence will have everything from start up // until the end of the array. func (a *Array) Range(start int, end ...int) []interface{} { a.mu.RLock() @@ -364,7 +373,7 @@ func (a *Array) Range(start int, end ...int) []interface{} { } // SubSlice returns a slice of elements from the array as specified -// by the and parameters. +// by the `offset` and `size` parameters. // If in concurrent safe usage, it returns a copy of the slice; else a pointer. // // If offset is non-negative, the sequence will start at that offset in the array. @@ -471,7 +480,7 @@ func (a *Array) Contains(value interface{}) bool { return a.Search(value) != -1 } -// Search searches array by , returns the index of , +// Search searches array by `value`, returns the index of `value`, // or returns -1 if not exists. func (a *Array) Search(value interface{}) int { a.mu.RLock() @@ -506,7 +515,7 @@ func (a *Array) Unique() *Array { return a } -// LockFunc locks writing by callback function . +// LockFunc locks writing by callback function `f`. func (a *Array) LockFunc(f func(array []interface{})) *Array { a.mu.Lock() defer a.mu.Unlock() @@ -514,7 +523,7 @@ func (a *Array) LockFunc(f func(array []interface{})) *Array { return a } -// RLockFunc locks reading by callback function . +// RLockFunc locks reading by callback function `f`. func (a *Array) RLockFunc(f func(array []interface{})) *Array { a.mu.RLock() defer a.mu.RUnlock() @@ -522,16 +531,16 @@ func (a *Array) RLockFunc(f func(array []interface{})) *Array { return a } -// Merge merges into current array. -// The parameter can be any garray or slice type. +// Merge merges `array` into current array. +// The parameter `array` can be any garray or slice type. // The difference between Merge and Append is Append supports only specified slice type, // but Merge supports more parameter types. func (a *Array) Merge(array interface{}) *Array { return a.Append(gconv.Interfaces(array)...) } -// Fill fills an array with num entries of the value , -// keys starting at the parameter. +// Fill fills an array with num entries of the value `value`, +// keys starting at the `startIndex` parameter. func (a *Array) Fill(startIndex int, num int, value interface{}) error { a.mu.Lock() defer a.mu.Unlock() @@ -549,7 +558,7 @@ func (a *Array) Fill(startIndex int, num int, value interface{}) error { } // Chunk splits an array into multiple arrays, -// the size of each array is determined by . +// the size of each array is determined by `size`. // The last chunk may contain less than size elements. func (a *Array) Chunk(size int) [][]interface{} { if size < 1 { @@ -571,9 +580,9 @@ func (a *Array) Chunk(size int) [][]interface{} { return n } -// Pad pads array to the specified length with . +// Pad pads array to the specified length with `value`. // If size is positive then the array is padded on the right, or negative on the left. -// If the absolute value of is less than or equal to the length of the array +// If the absolute value of `size` is less than or equal to the length of the array // then no padding takes place. func (a *Array) Pad(size int, val interface{}) *Array { a.mu.Lock() @@ -608,7 +617,7 @@ func (a *Array) Rand() (value interface{}, found bool) { return a.array[grand.Intn(len(a.array))], true } -// Rands randomly returns items from array(no deleting). +// Rands randomly returns `size` items from array(no deleting). func (a *Array) Rands(size int) []interface{} { a.mu.RLock() defer a.mu.RUnlock() @@ -642,7 +651,7 @@ func (a *Array) Reverse() *Array { return a } -// Join joins array elements with a string . +// Join joins array elements with a string `glue`. func (a *Array) Join(glue string) string { a.mu.RLock() defer a.mu.RUnlock() @@ -675,8 +684,8 @@ func (a *Array) Iterator(f func(k int, v interface{}) bool) { a.IteratorAsc(f) } -// IteratorAsc iterates the array readonly in ascending order with given callback function . -// If returns true, then it continues iterating; or false to stop. +// IteratorAsc iterates the array readonly in ascending order with given callback function `f`. +// If `f` returns true, then it continues iterating; or false to stop. func (a *Array) IteratorAsc(f func(k int, v interface{}) bool) { a.mu.RLock() defer a.mu.RUnlock() @@ -687,8 +696,8 @@ func (a *Array) IteratorAsc(f func(k int, v interface{}) bool) { } } -// IteratorDesc iterates the array readonly in descending order with given callback function . -// If returns true, then it continues iterating; or false to stop. +// IteratorDesc iterates the array readonly in descending order with given callback function `f`. +// If `f` returns true, then it continues iterating; or false to stop. func (a *Array) IteratorDesc(f func(k int, v interface{}) bool) { a.mu.RLock() defer a.mu.RUnlock() @@ -784,7 +793,7 @@ func (a *Array) FilterEmpty() *Array { return a } -// Walk applies a user supplied function to every item of array. +// Walk applies a user supplied function `f` to every item of array. func (a *Array) Walk(f func(value interface{}) interface{}) *Array { a.mu.Lock() defer a.mu.Unlock() diff --git a/container/garray/garray_normal_int.go b/container/garray/garray_normal_int.go index 10dbe16fe..05a10f0fe 100644 --- a/container/garray/garray_normal_int.go +++ b/container/garray/garray_normal_int.go @@ -28,14 +28,14 @@ type IntArray struct { } // NewIntArray creates and returns an empty array. -// The parameter is used to specify whether using array in concurrent-safety, +// The parameter `safe` is used to specify whether using array in concurrent-safety, // which is false in default. func NewIntArray(safe ...bool) *IntArray { return NewIntArraySize(0, 0, safe...) } // NewIntArraySize create and returns an array with given size and cap. -// The parameter is used to specify whether using array in concurrent-safety, +// The parameter `safe` is used to specify whether using array in concurrent-safety, // which is false in default. func NewIntArraySize(size int, cap int, safe ...bool) *IntArray { return &IntArray{ @@ -44,8 +44,8 @@ func NewIntArraySize(size int, cap int, safe ...bool) *IntArray { } } -// NewIntArrayRange creates and returns a array by a range from to -// with step value . +// NewIntArrayRange creates and returns a array by a range from `start` to `end` +// with step value `step`. func NewIntArrayRange(start, end, step int, safe ...bool) *IntArray { if step == 0 { panic(fmt.Sprintf(`invalid step value: %d`, step)) @@ -59,8 +59,8 @@ func NewIntArrayRange(start, end, step int, safe ...bool) *IntArray { return NewIntArrayFrom(slice, safe...) } -// NewIntArrayFrom creates and returns an array with given slice . -// The parameter is used to specify whether using array in concurrent-safety, +// NewIntArrayFrom creates and returns an array with given slice `array`. +// The parameter `safe` is used to specify whether using array in concurrent-safety, // which is false in default. func NewIntArrayFrom(array []int, safe ...bool) *IntArray { return &IntArray{ @@ -69,8 +69,8 @@ func NewIntArrayFrom(array []int, safe ...bool) *IntArray { } } -// NewIntArrayFromCopy creates and returns an array from a copy of given slice . -// The parameter is used to specify whether using array in concurrent-safety, +// NewIntArrayFromCopy creates and returns an array from a copy of given slice `array`. +// The parameter `safe` is used to specify whether using array in concurrent-safety, // which is false in default. func NewIntArrayFromCopy(array []int, safe ...bool) *IntArray { newArray := make([]int, len(array)) @@ -81,8 +81,15 @@ func NewIntArrayFromCopy(array []int, safe ...bool) *IntArray { } } +// At returns the value by the specified index. +// If the given `index` is out of range of the array, it returns `0`. +func (a *IntArray) At(index int) (value int) { + value, _ = a.Get(index) + return +} + // Get returns the value by the specified index. -// If the given is out of range of the array, the is false. +// If the given `index` is out of range of the array, the `found` is false. func (a *IntArray) Get(index int) (value int, found bool) { a.mu.RLock() defer a.mu.RUnlock() @@ -103,7 +110,7 @@ func (a *IntArray) Set(index int, value int) error { return nil } -// SetArray sets the underlying slice array with the given . +// SetArray sets the underlying slice array with the given `array`. func (a *IntArray) SetArray(array []int) *IntArray { a.mu.Lock() defer a.mu.Unlock() @@ -111,7 +118,7 @@ func (a *IntArray) SetArray(array []int) *IntArray { return a } -// Replace replaces the array items by given from the beginning of array. +// Replace replaces the array items by given `array` from the beginning of array. func (a *IntArray) Replace(array []int) *IntArray { a.mu.Lock() defer a.mu.Unlock() @@ -136,7 +143,7 @@ func (a *IntArray) Sum() (sum int) { } // Sort sorts the array in increasing order. -// The parameter controls whether sort in increasing order(default) or decreasing order. +// The parameter `reverse` controls whether sort in increasing order(default) or decreasing order. func (a *IntArray) Sort(reverse ...bool) *IntArray { a.mu.Lock() defer a.mu.Unlock() @@ -153,7 +160,7 @@ func (a *IntArray) Sort(reverse ...bool) *IntArray { return a } -// SortFunc sorts the array by custom function . +// SortFunc sorts the array by custom function `less`. func (a *IntArray) SortFunc(less func(v1, v2 int) bool) *IntArray { a.mu.Lock() defer a.mu.Unlock() @@ -163,7 +170,7 @@ func (a *IntArray) SortFunc(less func(v1, v2 int) bool) *IntArray { return a } -// InsertBefore inserts the to the front of . +// InsertBefore inserts the `value` to the front of `index`. func (a *IntArray) InsertBefore(index int, value int) error { a.mu.Lock() defer a.mu.Unlock() @@ -176,7 +183,7 @@ func (a *IntArray) InsertBefore(index int, value int) error { return nil } -// InsertAfter inserts the to the back of . +// InsertAfter inserts the `value` to the back of `index`. func (a *IntArray) InsertAfter(index int, value int) error { a.mu.Lock() defer a.mu.Unlock() @@ -190,7 +197,7 @@ func (a *IntArray) InsertAfter(index int, value int) error { } // Remove removes an item by index. -// If the given is out of range of the array, the is false. +// If the given `index` is out of range of the array, the `found` is false. func (a *IntArray) Remove(index int) (value int, found bool) { a.mu.Lock() defer a.mu.Unlock() @@ -248,7 +255,7 @@ func (a *IntArray) PushRight(value ...int) *IntArray { } // PopLeft pops and returns an item from the beginning of array. -// Note that if the array is empty, the is false. +// Note that if the array is empty, the `found` is false. func (a *IntArray) PopLeft() (value int, found bool) { a.mu.Lock() defer a.mu.Unlock() @@ -261,7 +268,7 @@ func (a *IntArray) PopLeft() (value int, found bool) { } // PopRight pops and returns an item from the end of array. -// Note that if the array is empty, the is false. +// Note that if the array is empty, the `found` is false. func (a *IntArray) PopRight() (value int, found bool) { a.mu.Lock() defer a.mu.Unlock() @@ -275,16 +282,16 @@ func (a *IntArray) PopRight() (value int, found bool) { } // PopRand randomly pops and return an item out of array. -// Note that if the array is empty, the is false. +// Note that if the array is empty, the `found` is false. func (a *IntArray) PopRand() (value int, found bool) { a.mu.Lock() defer a.mu.Unlock() return a.doRemoveWithoutLock(grand.Intn(len(a.array))) } -// PopRands randomly pops and returns items out of array. -// If the given is greater than size of the array, it returns all elements of the array. -// Note that if given <= 0 or the array is empty, it returns nil. +// PopRands randomly pops and returns `size` items out of array. +// If the given `size` is greater than size of the array, it returns all elements of the array. +// Note that if given `size` <= 0 or the array is empty, it returns nil. func (a *IntArray) PopRands(size int) []int { a.mu.Lock() defer a.mu.Unlock() @@ -301,9 +308,9 @@ func (a *IntArray) PopRands(size int) []int { return array } -// PopLefts pops and returns items from the beginning of array. -// If the given is greater than size of the array, it returns all elements of the array. -// Note that if given <= 0 or the array is empty, it returns nil. +// PopLefts pops and returns `size` items from the beginning of array. +// If the given `size` is greater than size of the array, it returns all elements of the array. +// Note that if given `size` <= 0 or the array is empty, it returns nil. func (a *IntArray) PopLefts(size int) []int { a.mu.Lock() defer a.mu.Unlock() @@ -320,9 +327,9 @@ func (a *IntArray) PopLefts(size int) []int { return value } -// PopRights pops and returns items from the end of array. -// If the given is greater than size of the array, it returns all elements of the array. -// Note that if given <= 0 or the array is empty, it returns nil. +// PopRights pops and returns `size` items from the end of array. +// If the given `size` is greater than size of the array, it returns all elements of the array. +// Note that if given `size` <= 0 or the array is empty, it returns nil. func (a *IntArray) PopRights(size int) []int { a.mu.Lock() defer a.mu.Unlock() @@ -344,8 +351,8 @@ func (a *IntArray) PopRights(size int) []int { // Notice, if in concurrent-safe usage, it returns a copy of slice; // else a pointer to the underlying data. // -// If is negative, then the offset will start from the end of array. -// If is omitted, then the sequence will have everything from start up +// If `end` is negative, then the offset will start from the end of array. +// If `end` is omitted, then the sequence will have everything from start up // until the end of the array. func (a *IntArray) Range(start int, end ...int) []int { a.mu.RLock() @@ -371,7 +378,7 @@ func (a *IntArray) Range(start int, end ...int) []int { } // SubSlice returns a slice of elements from the array as specified -// by the and parameters. +// by the `offset` and `size` parameters. // If in concurrent safe usage, it returns a copy of the slice; else a pointer. // // If offset is non-negative, the sequence will start at that offset in the array. @@ -487,7 +494,7 @@ func (a *IntArray) Contains(value int) bool { return a.Search(value) != -1 } -// Search searches array by , returns the index of , +// Search searches array by `value`, returns the index of `value`, // or returns -1 if not exists. func (a *IntArray) Search(value int) int { a.mu.RLock() @@ -522,7 +529,7 @@ func (a *IntArray) Unique() *IntArray { return a } -// LockFunc locks writing by callback function . +// LockFunc locks writing by callback function `f`. func (a *IntArray) LockFunc(f func(array []int)) *IntArray { a.mu.Lock() defer a.mu.Unlock() @@ -530,7 +537,7 @@ func (a *IntArray) LockFunc(f func(array []int)) *IntArray { return a } -// RLockFunc locks reading by callback function . +// RLockFunc locks reading by callback function `f`. func (a *IntArray) RLockFunc(f func(array []int)) *IntArray { a.mu.RLock() defer a.mu.RUnlock() @@ -538,16 +545,16 @@ func (a *IntArray) RLockFunc(f func(array []int)) *IntArray { return a } -// Merge merges into current array. -// The parameter can be any garray or slice type. +// Merge merges `array` into current array. +// The parameter `array` can be any garray or slice type. // The difference between Merge and Append is Append supports only specified slice type, // but Merge supports more parameter types. func (a *IntArray) Merge(array interface{}) *IntArray { return a.Append(gconv.Ints(array)...) } -// Fill fills an array with num entries of the value , -// keys starting at the parameter. +// Fill fills an array with num entries of the value `value`, +// keys starting at the `startIndex` parameter. func (a *IntArray) Fill(startIndex int, num int, value int) error { a.mu.Lock() defer a.mu.Unlock() @@ -565,7 +572,7 @@ func (a *IntArray) Fill(startIndex int, num int, value int) error { } // Chunk splits an array into multiple arrays, -// the size of each array is determined by . +// the size of each array is determined by `size`. // The last chunk may contain less than size elements. func (a *IntArray) Chunk(size int) [][]int { if size < 1 { @@ -587,9 +594,9 @@ func (a *IntArray) Chunk(size int) [][]int { return n } -// Pad pads array to the specified length with . +// Pad pads array to the specified length with `value`. // If size is positive then the array is padded on the right, or negative on the left. -// If the absolute value of is less than or equal to the length of the array +// If the absolute value of `size` is less than or equal to the length of the array // then no padding takes place. func (a *IntArray) Pad(size int, value int) *IntArray { a.mu.Lock() @@ -624,7 +631,7 @@ func (a *IntArray) Rand() (value int, found bool) { return a.array[grand.Intn(len(a.array))], true } -// Rands randomly returns items from array(no deleting). +// Rands randomly returns `size` items from array(no deleting). func (a *IntArray) Rands(size int) []int { a.mu.RLock() defer a.mu.RUnlock() @@ -658,7 +665,7 @@ func (a *IntArray) Reverse() *IntArray { return a } -// Join joins array elements with a string . +// Join joins array elements with a string `glue`. func (a *IntArray) Join(glue string) string { a.mu.RLock() defer a.mu.RUnlock() @@ -691,8 +698,8 @@ func (a *IntArray) Iterator(f func(k int, v int) bool) { a.IteratorAsc(f) } -// IteratorAsc iterates the array readonly in ascending order with given callback function . -// If returns true, then it continues iterating; or false to stop. +// IteratorAsc iterates the array readonly in ascending order with given callback function `f`. +// If `f` returns true, then it continues iterating; or false to stop. func (a *IntArray) IteratorAsc(f func(k int, v int) bool) { a.mu.RLock() defer a.mu.RUnlock() @@ -703,8 +710,8 @@ func (a *IntArray) IteratorAsc(f func(k int, v int) bool) { } } -// IteratorDesc iterates the array readonly in descending order with given callback function . -// If returns true, then it continues iterating; or false to stop. +// IteratorDesc iterates the array readonly in descending order with given callback function `f`. +// If `f` returns true, then it continues iterating; or false to stop. func (a *IntArray) IteratorDesc(f func(k int, v int) bool) { a.mu.RLock() defer a.mu.RUnlock() @@ -768,7 +775,7 @@ func (a *IntArray) FilterEmpty() *IntArray { return a } -// Walk applies a user supplied function to every item of array. +// Walk applies a user supplied function `f` to every item of array. func (a *IntArray) Walk(f func(value int) int) *IntArray { a.mu.Lock() defer a.mu.Unlock() diff --git a/container/garray/garray_normal_str.go b/container/garray/garray_normal_str.go index 523a75123..f1754e80d 100644 --- a/container/garray/garray_normal_str.go +++ b/container/garray/garray_normal_str.go @@ -30,14 +30,14 @@ type StrArray struct { } // NewStrArray creates and returns an empty array. -// The parameter is used to specify whether using array in concurrent-safety, +// The parameter `safe` is used to specify whether using array in concurrent-safety, // which is false in default. func NewStrArray(safe ...bool) *StrArray { return NewStrArraySize(0, 0, safe...) } // NewStrArraySize create and returns an array with given size and cap. -// The parameter is used to specify whether using array in concurrent-safety, +// The parameter `safe` is used to specify whether using array in concurrent-safety, // which is false in default. func NewStrArraySize(size int, cap int, safe ...bool) *StrArray { return &StrArray{ @@ -46,8 +46,8 @@ func NewStrArraySize(size int, cap int, safe ...bool) *StrArray { } } -// NewStrArrayFrom creates and returns an array with given slice . -// The parameter is used to specify whether using array in concurrent-safety, +// NewStrArrayFrom creates and returns an array with given slice `array`. +// The parameter `safe` is used to specify whether using array in concurrent-safety, // which is false in default. func NewStrArrayFrom(array []string, safe ...bool) *StrArray { return &StrArray{ @@ -56,8 +56,8 @@ func NewStrArrayFrom(array []string, safe ...bool) *StrArray { } } -// NewStrArrayFromCopy creates and returns an array from a copy of given slice . -// The parameter is used to specify whether using array in concurrent-safety, +// NewStrArrayFromCopy creates and returns an array from a copy of given slice `array`. +// The parameter `safe` is used to specify whether using array in concurrent-safety, // which is false in default. func NewStrArrayFromCopy(array []string, safe ...bool) *StrArray { newArray := make([]string, len(array)) @@ -68,8 +68,15 @@ func NewStrArrayFromCopy(array []string, safe ...bool) *StrArray { } } +// At returns the value by the specified index. +// If the given `index` is out of range of the array, it returns an empty string. +func (a *StrArray) At(index int) (value string) { + value, _ = a.Get(index) + return +} + // Get returns the value by the specified index. -// If the given is out of range of the array, the is false. +// If the given `index` is out of range of the array, the `found` is false. func (a *StrArray) Get(index int) (value string, found bool) { a.mu.RLock() defer a.mu.RUnlock() @@ -90,7 +97,7 @@ func (a *StrArray) Set(index int, value string) error { return nil } -// SetArray sets the underlying slice array with the given . +// SetArray sets the underlying slice array with the given `array`. func (a *StrArray) SetArray(array []string) *StrArray { a.mu.Lock() defer a.mu.Unlock() @@ -98,7 +105,7 @@ func (a *StrArray) SetArray(array []string) *StrArray { return a } -// Replace replaces the array items by given from the beginning of array. +// Replace replaces the array items by given `array` from the beginning of array. func (a *StrArray) Replace(array []string) *StrArray { a.mu.Lock() defer a.mu.Unlock() @@ -123,7 +130,7 @@ func (a *StrArray) Sum() (sum int) { } // Sort sorts the array in increasing order. -// The parameter controls whether sort +// The parameter `reverse` controls whether sort // in increasing order(default) or decreasing order func (a *StrArray) Sort(reverse ...bool) *StrArray { a.mu.Lock() @@ -141,7 +148,7 @@ func (a *StrArray) Sort(reverse ...bool) *StrArray { return a } -// SortFunc sorts the array by custom function . +// SortFunc sorts the array by custom function `less`. func (a *StrArray) SortFunc(less func(v1, v2 string) bool) *StrArray { a.mu.Lock() defer a.mu.Unlock() @@ -151,7 +158,7 @@ func (a *StrArray) SortFunc(less func(v1, v2 string) bool) *StrArray { return a } -// InsertBefore inserts the to the front of . +// InsertBefore inserts the `value` to the front of `index`. func (a *StrArray) InsertBefore(index int, value string) error { a.mu.Lock() defer a.mu.Unlock() @@ -164,7 +171,7 @@ func (a *StrArray) InsertBefore(index int, value string) error { return nil } -// InsertAfter inserts the to the back of . +// InsertAfter inserts the `value` to the back of `index`. func (a *StrArray) InsertAfter(index int, value string) error { a.mu.Lock() defer a.mu.Unlock() @@ -178,7 +185,7 @@ func (a *StrArray) InsertAfter(index int, value string) error { } // Remove removes an item by index. -// If the given is out of range of the array, the is false. +// If the given `index` is out of range of the array, the `found` is false. func (a *StrArray) Remove(index int) (value string, found bool) { a.mu.Lock() defer a.mu.Unlock() @@ -236,7 +243,7 @@ func (a *StrArray) PushRight(value ...string) *StrArray { } // PopLeft pops and returns an item from the beginning of array. -// Note that if the array is empty, the is false. +// Note that if the array is empty, the `found` is false. func (a *StrArray) PopLeft() (value string, found bool) { a.mu.Lock() defer a.mu.Unlock() @@ -249,7 +256,7 @@ func (a *StrArray) PopLeft() (value string, found bool) { } // PopRight pops and returns an item from the end of array. -// Note that if the array is empty, the is false. +// Note that if the array is empty, the `found` is false. func (a *StrArray) PopRight() (value string, found bool) { a.mu.Lock() defer a.mu.Unlock() @@ -263,16 +270,16 @@ func (a *StrArray) PopRight() (value string, found bool) { } // PopRand randomly pops and return an item out of array. -// Note that if the array is empty, the is false. +// Note that if the array is empty, the `found` is false. func (a *StrArray) PopRand() (value string, found bool) { a.mu.Lock() defer a.mu.Unlock() return a.doRemoveWithoutLock(grand.Intn(len(a.array))) } -// PopRands randomly pops and returns items out of array. -// If the given is greater than size of the array, it returns all elements of the array. -// Note that if given <= 0 or the array is empty, it returns nil. +// PopRands randomly pops and returns `size` items out of array. +// If the given `size` is greater than size of the array, it returns all elements of the array. +// Note that if given `size` <= 0 or the array is empty, it returns nil. func (a *StrArray) PopRands(size int) []string { a.mu.Lock() defer a.mu.Unlock() @@ -289,9 +296,9 @@ func (a *StrArray) PopRands(size int) []string { return array } -// PopLefts pops and returns items from the beginning of array. -// If the given is greater than size of the array, it returns all elements of the array. -// Note that if given <= 0 or the array is empty, it returns nil. +// PopLefts pops and returns `size` items from the beginning of array. +// If the given `size` is greater than size of the array, it returns all elements of the array. +// Note that if given `size` <= 0 or the array is empty, it returns nil. func (a *StrArray) PopLefts(size int) []string { a.mu.Lock() defer a.mu.Unlock() @@ -308,9 +315,9 @@ func (a *StrArray) PopLefts(size int) []string { return value } -// PopRights pops and returns items from the end of array. -// If the given is greater than size of the array, it returns all elements of the array. -// Note that if given <= 0 or the array is empty, it returns nil. +// PopRights pops and returns `size` items from the end of array. +// If the given `size` is greater than size of the array, it returns all elements of the array. +// Note that if given `size` <= 0 or the array is empty, it returns nil. func (a *StrArray) PopRights(size int) []string { a.mu.Lock() defer a.mu.Unlock() @@ -332,8 +339,8 @@ func (a *StrArray) PopRights(size int) []string { // Notice, if in concurrent-safe usage, it returns a copy of slice; // else a pointer to the underlying data. // -// If is negative, then the offset will start from the end of array. -// If is omitted, then the sequence will have everything from start up +// If `end` is negative, then the offset will start from the end of array. +// If `end` is omitted, then the sequence will have everything from start up // until the end of the array. func (a *StrArray) Range(start int, end ...int) []string { a.mu.RLock() @@ -359,7 +366,7 @@ func (a *StrArray) Range(start int, end ...int) []string { } // SubSlice returns a slice of elements from the array as specified -// by the and parameters. +// by the `offset` and `size` parameters. // If in concurrent safe usage, it returns a copy of the slice; else a pointer. // // If offset is non-negative, the sequence will start at that offset in the array. @@ -491,7 +498,7 @@ func (a *StrArray) ContainsI(value string) bool { return false } -// Search searches array by , returns the index of , +// Search searches array by `value`, returns the index of `value`, // or returns -1 if not exists. func (a *StrArray) Search(value string) int { a.mu.RLock() @@ -526,7 +533,7 @@ func (a *StrArray) Unique() *StrArray { return a } -// LockFunc locks writing by callback function . +// LockFunc locks writing by callback function `f`. func (a *StrArray) LockFunc(f func(array []string)) *StrArray { a.mu.Lock() defer a.mu.Unlock() @@ -534,7 +541,7 @@ func (a *StrArray) LockFunc(f func(array []string)) *StrArray { return a } -// RLockFunc locks reading by callback function . +// RLockFunc locks reading by callback function `f`. func (a *StrArray) RLockFunc(f func(array []string)) *StrArray { a.mu.RLock() defer a.mu.RUnlock() @@ -542,16 +549,16 @@ func (a *StrArray) RLockFunc(f func(array []string)) *StrArray { return a } -// Merge merges into current array. -// The parameter can be any garray or slice type. +// Merge merges `array` into current array. +// The parameter `array` can be any garray or slice type. // The difference between Merge and Append is Append supports only specified slice type, // but Merge supports more parameter types. func (a *StrArray) Merge(array interface{}) *StrArray { return a.Append(gconv.Strings(array)...) } -// Fill fills an array with num entries of the value , -// keys starting at the parameter. +// Fill fills an array with num entries of the value `value`, +// keys starting at the `startIndex` parameter. func (a *StrArray) Fill(startIndex int, num int, value string) error { a.mu.Lock() defer a.mu.Unlock() @@ -569,7 +576,7 @@ func (a *StrArray) Fill(startIndex int, num int, value string) error { } // Chunk splits an array into multiple arrays, -// the size of each array is determined by . +// the size of each array is determined by `size`. // The last chunk may contain less than size elements. func (a *StrArray) Chunk(size int) [][]string { if size < 1 { @@ -591,9 +598,9 @@ func (a *StrArray) Chunk(size int) [][]string { return n } -// Pad pads array to the specified length with . +// Pad pads array to the specified length with `value`. // If size is positive then the array is padded on the right, or negative on the left. -// If the absolute value of is less than or equal to the length of the array +// If the absolute value of `size` is less than or equal to the length of the array // then no padding takes place. func (a *StrArray) Pad(size int, value string) *StrArray { a.mu.Lock() @@ -628,7 +635,7 @@ func (a *StrArray) Rand() (value string, found bool) { return a.array[grand.Intn(len(a.array))], true } -// Rands randomly returns items from array(no deleting). +// Rands randomly returns `size` items from array(no deleting). func (a *StrArray) Rands(size int) []string { a.mu.RLock() defer a.mu.RUnlock() @@ -662,7 +669,7 @@ func (a *StrArray) Reverse() *StrArray { return a } -// Join joins array elements with a string . +// Join joins array elements with a string `glue`. func (a *StrArray) Join(glue string) string { a.mu.RLock() defer a.mu.RUnlock() @@ -695,8 +702,8 @@ func (a *StrArray) Iterator(f func(k int, v string) bool) { a.IteratorAsc(f) } -// IteratorAsc iterates the array readonly in ascending order with given callback function . -// If returns true, then it continues iterating; or false to stop. +// IteratorAsc iterates the array readonly in ascending order with given callback function `f`. +// If `f` returns true, then it continues iterating; or false to stop. func (a *StrArray) IteratorAsc(f func(k int, v string) bool) { a.mu.RLock() defer a.mu.RUnlock() @@ -707,8 +714,8 @@ func (a *StrArray) IteratorAsc(f func(k int, v string) bool) { } } -// IteratorDesc iterates the array readonly in descending order with given callback function . -// If returns true, then it continues iterating; or false to stop. +// IteratorDesc iterates the array readonly in descending order with given callback function `f`. +// If `f` returns true, then it continues iterating; or false to stop. func (a *StrArray) IteratorDesc(f func(k int, v string) bool) { a.mu.RLock() defer a.mu.RUnlock() @@ -783,7 +790,7 @@ func (a *StrArray) FilterEmpty() *StrArray { return a } -// Walk applies a user supplied function to every item of array. +// Walk applies a user supplied function `f` to every item of array. func (a *StrArray) Walk(f func(value string) string) *StrArray { a.mu.Lock() defer a.mu.Unlock() diff --git a/container/garray/garray_sorted_any.go b/container/garray/garray_sorted_any.go index 91d7fa073..cd14d6252 100644 --- a/container/garray/garray_sorted_any.go +++ b/container/garray/garray_sorted_any.go @@ -34,8 +34,8 @@ type SortedArray struct { } // NewSortedArray creates and returns an empty sorted array. -// The parameter is used to specify whether using array in concurrent-safety, which is false in default. -// The parameter used to compare values to sort in array, +// The parameter `safe` is used to specify whether using array in concurrent-safety, which is false in default. +// The parameter `comparator` used to compare values to sort in array, // if it returns value < 0, means v1 < v2; the v1 will be inserted before v2; // if it returns value = 0, means v1 = v2; the v1 will be replaced by v2; // if it returns value > 0, means v1 > v2; the v1 will be inserted after v2; @@ -44,7 +44,7 @@ func NewSortedArray(comparator func(a, b interface{}) int, safe ...bool) *Sorted } // NewSortedArraySize create and returns an sorted array with given size and cap. -// The parameter is used to specify whether using array in concurrent-safety, +// The parameter `safe` is used to specify whether using array in concurrent-safety, // which is false in default. func NewSortedArraySize(cap int, comparator func(a, b interface{}) int, safe ...bool) *SortedArray { return &SortedArray{ @@ -54,8 +54,8 @@ func NewSortedArraySize(cap int, comparator func(a, b interface{}) int, safe ... } } -// NewSortedArrayRange creates and returns a array by a range from to -// with step value . +// NewSortedArrayRange creates and returns a array by a range from `start` to `end` +// with step value `step`. func NewSortedArrayRange(start, end, step int, comparator func(a, b interface{}) int, safe ...bool) *SortedArray { if step == 0 { panic(fmt.Sprintf(`invalid step value: %d`, step)) @@ -69,8 +69,8 @@ func NewSortedArrayRange(start, end, step int, comparator func(a, b interface{}) return NewSortedArrayFrom(slice, comparator, safe...) } -// NewSortedArrayFrom creates and returns an sorted array with given slice . -// The parameter is used to specify whether using array in concurrent-safety, +// NewSortedArrayFrom creates and returns an sorted array with given slice `array`. +// The parameter `safe` is used to specify whether using array in concurrent-safety, // which is false in default. func NewSortedArrayFrom(array []interface{}, comparator func(a, b interface{}) int, safe ...bool) *SortedArray { a := NewSortedArraySize(0, comparator, safe...) @@ -81,8 +81,8 @@ func NewSortedArrayFrom(array []interface{}, comparator func(a, b interface{}) i return a } -// NewSortedArrayFromCopy creates and returns an sorted array from a copy of given slice . -// The parameter is used to specify whether using array in concurrent-safety, +// NewSortedArrayFromCopy creates and returns an sorted array from a copy of given slice `array`. +// The parameter `safe` is used to specify whether using array in concurrent-safety, // which is false in default. func NewSortedArrayFromCopy(array []interface{}, comparator func(a, b interface{}) int, safe ...bool) *SortedArray { newArray := make([]interface{}, len(array)) @@ -90,7 +90,14 @@ func NewSortedArrayFromCopy(array []interface{}, comparator func(a, b interface{ return NewSortedArrayFrom(newArray, comparator, safe...) } -// SetArray sets the underlying slice array with the given . +// At returns the value by the specified index. +// If the given `index` is out of range of the array, it returns `nil`. +func (a *SortedArray) At(index int) (value interface{}) { + value, _ = a.Get(index) + return +} + +// SetArray sets the underlying slice array with the given `array`. func (a *SortedArray) SetArray(array []interface{}) *SortedArray { a.mu.Lock() defer a.mu.Unlock() @@ -113,7 +120,7 @@ func (a *SortedArray) SetComparator(comparator func(a, b interface{}) int) { } // Sort sorts the array in increasing order. -// The parameter controls whether sort +// The parameter `reverse` controls whether sort // in increasing order(default) or decreasing order func (a *SortedArray) Sort() *SortedArray { a.mu.Lock() @@ -157,7 +164,7 @@ func (a *SortedArray) Append(values ...interface{}) *SortedArray { } // Get returns the value by the specified index. -// If the given is out of range of the array, the is false. +// If the given `index` is out of range of the array, the `found` is false. func (a *SortedArray) Get(index int) (value interface{}, found bool) { a.mu.RLock() defer a.mu.RUnlock() @@ -168,7 +175,7 @@ func (a *SortedArray) Get(index int) (value interface{}, found bool) { } // Remove removes an item by index. -// If the given is out of range of the array, the is false. +// If the given `index` is out of range of the array, the `found` is false. func (a *SortedArray) Remove(index int) (value interface{}, found bool) { a.mu.Lock() defer a.mu.Unlock() @@ -209,7 +216,7 @@ func (a *SortedArray) RemoveValue(value interface{}) bool { } // PopLeft pops and returns an item from the beginning of array. -// Note that if the array is empty, the is false. +// Note that if the array is empty, the `found` is false. func (a *SortedArray) PopLeft() (value interface{}, found bool) { a.mu.Lock() defer a.mu.Unlock() @@ -222,7 +229,7 @@ func (a *SortedArray) PopLeft() (value interface{}, found bool) { } // PopRight pops and returns an item from the end of array. -// Note that if the array is empty, the is false. +// Note that if the array is empty, the `found` is false. func (a *SortedArray) PopRight() (value interface{}, found bool) { a.mu.Lock() defer a.mu.Unlock() @@ -236,14 +243,14 @@ func (a *SortedArray) PopRight() (value interface{}, found bool) { } // PopRand randomly pops and return an item out of array. -// Note that if the array is empty, the is false. +// Note that if the array is empty, the `found` is false. func (a *SortedArray) PopRand() (value interface{}, found bool) { a.mu.Lock() defer a.mu.Unlock() return a.doRemoveWithoutLock(grand.Intn(len(a.array))) } -// PopRands randomly pops and returns items out of array. +// PopRands randomly pops and returns `size` items out of array. func (a *SortedArray) PopRands(size int) []interface{} { a.mu.Lock() defer a.mu.Unlock() @@ -260,7 +267,7 @@ func (a *SortedArray) PopRands(size int) []interface{} { return array } -// PopLefts pops and returns items from the beginning of array. +// PopLefts pops and returns `size` items from the beginning of array. func (a *SortedArray) PopLefts(size int) []interface{} { a.mu.Lock() defer a.mu.Unlock() @@ -277,7 +284,7 @@ func (a *SortedArray) PopLefts(size int) []interface{} { return value } -// PopRights pops and returns items from the end of array. +// PopRights pops and returns `size` items from the end of array. func (a *SortedArray) PopRights(size int) []interface{} { a.mu.Lock() defer a.mu.Unlock() @@ -299,8 +306,8 @@ func (a *SortedArray) PopRights(size int) []interface{} { // Notice, if in concurrent-safe usage, it returns a copy of slice; // else a pointer to the underlying data. // -// If is negative, then the offset will start from the end of array. -// If is omitted, then the sequence will have everything from start up +// If `end` is negative, then the offset will start from the end of array. +// If `end` is omitted, then the sequence will have everything from start up // until the end of the array. func (a *SortedArray) Range(start int, end ...int) []interface{} { a.mu.RLock() @@ -326,7 +333,7 @@ func (a *SortedArray) Range(start int, end ...int) []interface{} { } // SubSlice returns a slice of elements from the array as specified -// by the and parameters. +// by the `offset` and `size` parameters. // If in concurrent safe usage, it returns a copy of the slice; else a pointer. // // If offset is non-negative, the sequence will start at that offset in the array. @@ -419,7 +426,7 @@ func (a *SortedArray) Contains(value interface{}) bool { return a.Search(value) != -1 } -// Search searches array by , returns the index of , +// Search searches array by `value`, returns the index of `value`, // or returns -1 if not exists. func (a *SortedArray) Search(value interface{}) (index int) { if i, r := a.binSearch(value, true); r == 0 { @@ -430,9 +437,9 @@ func (a *SortedArray) Search(value interface{}) (index int) { // Binary search. // It returns the last compared index and the result. -// If equals to 0, it means the value at is equals to . -// If lesser than 0, it means the value at is lesser than . -// If greater than 0, it means the value at is greater than . +// If `result` equals to 0, it means the value at `index` is equals to `value`. +// If `result` lesser than 0, it means the value at `index` is lesser than `value`. +// If `result` greater than 0, it means the value at `index` is greater than `value`. func (a *SortedArray) binSearch(value interface{}, lock bool) (index int, result int) { if lock { a.mu.RLock() @@ -512,7 +519,7 @@ func (a *SortedArray) Clear() *SortedArray { return a } -// LockFunc locks writing by callback function . +// LockFunc locks writing by callback function `f`. func (a *SortedArray) LockFunc(f func(array []interface{})) *SortedArray { a.mu.Lock() defer a.mu.Unlock() @@ -526,7 +533,7 @@ func (a *SortedArray) LockFunc(f func(array []interface{})) *SortedArray { return a } -// RLockFunc locks reading by callback function . +// RLockFunc locks reading by callback function `f`. func (a *SortedArray) RLockFunc(f func(array []interface{})) *SortedArray { a.mu.RLock() defer a.mu.RUnlock() @@ -534,8 +541,8 @@ func (a *SortedArray) RLockFunc(f func(array []interface{})) *SortedArray { return a } -// Merge merges into current array. -// The parameter can be any garray or slice type. +// Merge merges `array` into current array. +// The parameter `array` can be any garray or slice type. // The difference between Merge and Append is Append supports only specified slice type, // but Merge supports more parameter types. func (a *SortedArray) Merge(array interface{}) *SortedArray { @@ -543,7 +550,7 @@ func (a *SortedArray) Merge(array interface{}) *SortedArray { } // Chunk splits an array into multiple arrays, -// the size of each array is determined by . +// the size of each array is determined by `size`. // The last chunk may contain less than size elements. func (a *SortedArray) Chunk(size int) [][]interface{} { if size < 1 { @@ -575,7 +582,7 @@ func (a *SortedArray) Rand() (value interface{}, found bool) { return a.array[grand.Intn(len(a.array))], true } -// Rands randomly returns items from array(no deleting). +// Rands randomly returns `size` items from array(no deleting). func (a *SortedArray) Rands(size int) []interface{} { a.mu.RLock() defer a.mu.RUnlock() @@ -589,7 +596,7 @@ func (a *SortedArray) Rands(size int) []interface{} { return array } -// Join joins array elements with a string . +// Join joins array elements with a string `glue`. func (a *SortedArray) Join(glue string) string { a.mu.RLock() defer a.mu.RUnlock() @@ -622,8 +629,8 @@ func (a *SortedArray) Iterator(f func(k int, v interface{}) bool) { a.IteratorAsc(f) } -// IteratorAsc iterates the array readonly in ascending order with given callback function . -// If returns true, then it continues iterating; or false to stop. +// IteratorAsc iterates the array readonly in ascending order with given callback function `f`. +// If `f` returns true, then it continues iterating; or false to stop. func (a *SortedArray) IteratorAsc(f func(k int, v interface{}) bool) { a.mu.RLock() defer a.mu.RUnlock() @@ -634,8 +641,8 @@ func (a *SortedArray) IteratorAsc(f func(k int, v interface{}) bool) { } } -// IteratorDesc iterates the array readonly in descending order with given callback function . -// If returns true, then it continues iterating; or false to stop. +// IteratorDesc iterates the array readonly in descending order with given callback function `f`. +// If `f` returns true, then it continues iterating; or false to stop. func (a *SortedArray) IteratorDesc(f func(k int, v interface{}) bool) { a.mu.RLock() defer a.mu.RUnlock() @@ -761,7 +768,7 @@ func (a *SortedArray) FilterEmpty() *SortedArray { return a } -// Walk applies a user supplied function to every item of array. +// Walk applies a user supplied function `f` to every item of array. func (a *SortedArray) Walk(f func(value interface{}) interface{}) *SortedArray { a.mu.Lock() defer a.mu.Unlock() diff --git a/container/garray/garray_sorted_int.go b/container/garray/garray_sorted_int.go index 6b96b2c3a..f250d989c 100644 --- a/container/garray/garray_sorted_int.go +++ b/container/garray/garray_sorted_int.go @@ -31,14 +31,14 @@ type SortedIntArray struct { } // NewSortedIntArray creates and returns an empty sorted array. -// The parameter is used to specify whether using array in concurrent-safety, +// The parameter `safe` is used to specify whether using array in concurrent-safety, // which is false in default. func NewSortedIntArray(safe ...bool) *SortedIntArray { return NewSortedIntArraySize(0, safe...) } // NewSortedIntArrayComparator creates and returns an empty sorted array with specified comparator. -// The parameter is used to specify whether using array in concurrent-safety which is false in default. +// The parameter `safe` is used to specify whether using array in concurrent-safety which is false in default. func NewSortedIntArrayComparator(comparator func(a, b int) int, safe ...bool) *SortedIntArray { array := NewSortedIntArray(safe...) array.comparator = comparator @@ -46,7 +46,7 @@ func NewSortedIntArrayComparator(comparator func(a, b int) int, safe ...bool) *S } // NewSortedIntArraySize create and returns an sorted array with given size and cap. -// The parameter is used to specify whether using array in concurrent-safety, +// The parameter `safe` is used to specify whether using array in concurrent-safety, // which is false in default. func NewSortedIntArraySize(cap int, safe ...bool) *SortedIntArray { return &SortedIntArray{ @@ -56,8 +56,8 @@ func NewSortedIntArraySize(cap int, safe ...bool) *SortedIntArray { } } -// NewSortedIntArrayRange creates and returns a array by a range from to -// with step value . +// NewSortedIntArrayRange creates and returns a array by a range from `start` to `end` +// with step value `step`. func NewSortedIntArrayRange(start, end, step int, safe ...bool) *SortedIntArray { if step == 0 { panic(fmt.Sprintf(`invalid step value: %d`, step)) @@ -71,8 +71,8 @@ func NewSortedIntArrayRange(start, end, step int, safe ...bool) *SortedIntArray return NewSortedIntArrayFrom(slice, safe...) } -// NewIntArrayFrom creates and returns an sorted array with given slice . -// The parameter is used to specify whether using array in concurrent-safety, +// NewSortedIntArrayFrom creates and returns an sorted array with given slice `array`. +// The parameter `safe` is used to specify whether using array in concurrent-safety, // which is false in default. func NewSortedIntArrayFrom(array []int, safe ...bool) *SortedIntArray { a := NewSortedIntArraySize(0, safe...) @@ -81,8 +81,8 @@ func NewSortedIntArrayFrom(array []int, safe ...bool) *SortedIntArray { return a } -// NewSortedIntArrayFromCopy creates and returns an sorted array from a copy of given slice . -// The parameter is used to specify whether using array in concurrent-safety, +// NewSortedIntArrayFromCopy creates and returns an sorted array from a copy of given slice `array`. +// The parameter `safe` is used to specify whether using array in concurrent-safety, // which is false in default. func NewSortedIntArrayFromCopy(array []int, safe ...bool) *SortedIntArray { newArray := make([]int, len(array)) @@ -90,7 +90,14 @@ func NewSortedIntArrayFromCopy(array []int, safe ...bool) *SortedIntArray { return NewSortedIntArrayFrom(newArray, safe...) } -// SetArray sets the underlying slice array with the given . +// At returns the value by the specified index. +// If the given `index` is out of range of the array, it returns `0`. +func (a *SortedIntArray) At(index int) (value int) { + value, _ = a.Get(index) + return +} + +// SetArray sets the underlying slice array with the given `array`. func (a *SortedIntArray) SetArray(array []int) *SortedIntArray { a.mu.Lock() defer a.mu.Unlock() @@ -100,7 +107,7 @@ func (a *SortedIntArray) SetArray(array []int) *SortedIntArray { } // Sort sorts the array in increasing order. -// The parameter controls whether sort +// The parameter `reverse` controls whether sort // in increasing order(default) or decreasing order. func (a *SortedIntArray) Sort() *SortedIntArray { a.mu.Lock() @@ -142,7 +149,7 @@ func (a *SortedIntArray) Append(values ...int) *SortedIntArray { } // Get returns the value by the specified index. -// If the given is out of range of the array, the is false. +// If the given `index` is out of range of the array, the `found` is false. func (a *SortedIntArray) Get(index int) (value int, found bool) { a.mu.RLock() defer a.mu.RUnlock() @@ -153,7 +160,7 @@ func (a *SortedIntArray) Get(index int) (value int, found bool) { } // Remove removes an item by index. -// If the given is out of range of the array, the is false. +// If the given `index` is out of range of the array, the `found` is false. func (a *SortedIntArray) Remove(index int) (value int, found bool) { a.mu.Lock() defer a.mu.Unlock() @@ -194,7 +201,7 @@ func (a *SortedIntArray) RemoveValue(value int) bool { } // PopLeft pops and returns an item from the beginning of array. -// Note that if the array is empty, the is false. +// Note that if the array is empty, the `found` is false. func (a *SortedIntArray) PopLeft() (value int, found bool) { a.mu.Lock() defer a.mu.Unlock() @@ -207,7 +214,7 @@ func (a *SortedIntArray) PopLeft() (value int, found bool) { } // PopRight pops and returns an item from the end of array. -// Note that if the array is empty, the is false. +// Note that if the array is empty, the `found` is false. func (a *SortedIntArray) PopRight() (value int, found bool) { a.mu.Lock() defer a.mu.Unlock() @@ -221,16 +228,16 @@ func (a *SortedIntArray) PopRight() (value int, found bool) { } // PopRand randomly pops and return an item out of array. -// Note that if the array is empty, the is false. +// Note that if the array is empty, the `found` is false. func (a *SortedIntArray) PopRand() (value int, found bool) { a.mu.Lock() defer a.mu.Unlock() return a.doRemoveWithoutLock(grand.Intn(len(a.array))) } -// PopRands randomly pops and returns items out of array. -// If the given is greater than size of the array, it returns all elements of the array. -// Note that if given <= 0 or the array is empty, it returns nil. +// PopRands randomly pops and returns `size` items out of array. +// If the given `size` is greater than size of the array, it returns all elements of the array. +// Note that if given `size` <= 0 or the array is empty, it returns nil. func (a *SortedIntArray) PopRands(size int) []int { a.mu.Lock() defer a.mu.Unlock() @@ -247,9 +254,9 @@ func (a *SortedIntArray) PopRands(size int) []int { return array } -// PopLefts pops and returns items from the beginning of array. -// If the given is greater than size of the array, it returns all elements of the array. -// Note that if given <= 0 or the array is empty, it returns nil. +// PopLefts pops and returns `size` items from the beginning of array. +// If the given `size` is greater than size of the array, it returns all elements of the array. +// Note that if given `size` <= 0 or the array is empty, it returns nil. func (a *SortedIntArray) PopLefts(size int) []int { a.mu.Lock() defer a.mu.Unlock() @@ -266,9 +273,9 @@ func (a *SortedIntArray) PopLefts(size int) []int { return value } -// PopRights pops and returns items from the end of array. -// If the given is greater than size of the array, it returns all elements of the array. -// Note that if given <= 0 or the array is empty, it returns nil. +// PopRights pops and returns `size` items from the end of array. +// If the given `size` is greater than size of the array, it returns all elements of the array. +// Note that if given `size` <= 0 or the array is empty, it returns nil. func (a *SortedIntArray) PopRights(size int) []int { a.mu.Lock() defer a.mu.Unlock() @@ -290,8 +297,8 @@ func (a *SortedIntArray) PopRights(size int) []int { // Notice, if in concurrent-safe usage, it returns a copy of slice; // else a pointer to the underlying data. // -// If is negative, then the offset will start from the end of array. -// If is omitted, then the sequence will have everything from start up +// If `end` is negative, then the offset will start from the end of array. +// If `end` is omitted, then the sequence will have everything from start up // until the end of the array. func (a *SortedIntArray) Range(start int, end ...int) []int { a.mu.RLock() @@ -317,7 +324,7 @@ func (a *SortedIntArray) Range(start int, end ...int) []int { } // SubSlice returns a slice of elements from the array as specified -// by the and parameters. +// by the `offset` and `size` parameters. // If in concurrent safe usage, it returns a copy of the slice; else a pointer. // // If offset is non-negative, the sequence will start at that offset in the array. @@ -416,7 +423,7 @@ func (a *SortedIntArray) Contains(value int) bool { return a.Search(value) != -1 } -// Search searches array by , returns the index of , +// Search searches array by `value`, returns the index of `value`, // or returns -1 if not exists. func (a *SortedIntArray) Search(value int) (index int) { if i, r := a.binSearch(value, true); r == 0 { @@ -427,9 +434,9 @@ func (a *SortedIntArray) Search(value int) (index int) { // Binary search. // It returns the last compared index and the result. -// If equals to 0, it means the value at is equals to . -// If lesser than 0, it means the value at is lesser than . -// If greater than 0, it means the value at is greater than . +// If `result` equals to 0, it means the value at `index` is equals to `value`. +// If `result` lesser than 0, it means the value at `index` is lesser than `value`. +// If `result` greater than 0, it means the value at `index` is greater than `value`. func (a *SortedIntArray) binSearch(value int, lock bool) (index int, result int) { if lock { a.mu.RLock() @@ -509,7 +516,7 @@ func (a *SortedIntArray) Clear() *SortedIntArray { return a } -// LockFunc locks writing by callback function . +// LockFunc locks writing by callback function `f`. func (a *SortedIntArray) LockFunc(f func(array []int)) *SortedIntArray { a.mu.Lock() defer a.mu.Unlock() @@ -517,7 +524,7 @@ func (a *SortedIntArray) LockFunc(f func(array []int)) *SortedIntArray { return a } -// RLockFunc locks reading by callback function . +// RLockFunc locks reading by callback function `f`. func (a *SortedIntArray) RLockFunc(f func(array []int)) *SortedIntArray { a.mu.RLock() defer a.mu.RUnlock() @@ -525,8 +532,8 @@ func (a *SortedIntArray) RLockFunc(f func(array []int)) *SortedIntArray { return a } -// Merge merges into current array. -// The parameter can be any garray or slice type. +// Merge merges `array` into current array. +// The parameter `array` can be any garray or slice type. // The difference between Merge and Append is Append supports only specified slice type, // but Merge supports more parameter types. func (a *SortedIntArray) Merge(array interface{}) *SortedIntArray { @@ -534,7 +541,7 @@ func (a *SortedIntArray) Merge(array interface{}) *SortedIntArray { } // Chunk splits an array into multiple arrays, -// the size of each array is determined by . +// the size of each array is determined by `size`. // The last chunk may contain less than size elements. func (a *SortedIntArray) Chunk(size int) [][]int { if size < 1 { @@ -566,7 +573,7 @@ func (a *SortedIntArray) Rand() (value int, found bool) { return a.array[grand.Intn(len(a.array))], true } -// Rands randomly returns items from array(no deleting). +// Rands randomly returns `size` items from array(no deleting). func (a *SortedIntArray) Rands(size int) []int { a.mu.RLock() defer a.mu.RUnlock() @@ -580,7 +587,7 @@ func (a *SortedIntArray) Rands(size int) []int { return array } -// Join joins array elements with a string . +// Join joins array elements with a string `glue`. func (a *SortedIntArray) Join(glue string) string { a.mu.RLock() defer a.mu.RUnlock() @@ -613,8 +620,8 @@ func (a *SortedIntArray) Iterator(f func(k int, v int) bool) { a.IteratorAsc(f) } -// IteratorAsc iterates the array readonly in ascending order with given callback function . -// If returns true, then it continues iterating; or false to stop. +// IteratorAsc iterates the array readonly in ascending order with given callback function `f`. +// If `f` returns true, then it continues iterating; or false to stop. func (a *SortedIntArray) IteratorAsc(f func(k int, v int) bool) { a.mu.RLock() defer a.mu.RUnlock() @@ -625,8 +632,8 @@ func (a *SortedIntArray) IteratorAsc(f func(k int, v int) bool) { } } -// IteratorDesc iterates the array readonly in descending order with given callback function . -// If returns true, then it continues iterating; or false to stop. +// IteratorDesc iterates the array readonly in descending order with given callback function `f`. +// If `f` returns true, then it continues iterating; or false to stop. func (a *SortedIntArray) IteratorDesc(f func(k int, v int) bool) { a.mu.RLock() defer a.mu.RUnlock() @@ -707,7 +714,7 @@ func (a *SortedIntArray) FilterEmpty() *SortedIntArray { return a } -// Walk applies a user supplied function to every item of array. +// Walk applies a user supplied function `f` to every item of array. func (a *SortedIntArray) Walk(f func(value int) int) *SortedIntArray { a.mu.Lock() defer a.mu.Unlock() diff --git a/container/garray/garray_sorted_str.go b/container/garray/garray_sorted_str.go index 7b8e23b1b..896030e65 100644 --- a/container/garray/garray_sorted_str.go +++ b/container/garray/garray_sorted_str.go @@ -32,14 +32,14 @@ type SortedStrArray struct { } // NewSortedStrArray creates and returns an empty sorted array. -// The parameter is used to specify whether using array in concurrent-safety, +// The parameter `safe` is used to specify whether using array in concurrent-safety, // which is false in default. func NewSortedStrArray(safe ...bool) *SortedStrArray { return NewSortedStrArraySize(0, safe...) } // NewSortedStrArrayComparator creates and returns an empty sorted array with specified comparator. -// The parameter is used to specify whether using array in concurrent-safety which is false in default. +// The parameter `safe` is used to specify whether using array in concurrent-safety which is false in default. func NewSortedStrArrayComparator(comparator func(a, b string) int, safe ...bool) *SortedStrArray { array := NewSortedStrArray(safe...) array.comparator = comparator @@ -47,7 +47,7 @@ func NewSortedStrArrayComparator(comparator func(a, b string) int, safe ...bool) } // NewSortedStrArraySize create and returns an sorted array with given size and cap. -// The parameter is used to specify whether using array in concurrent-safety, +// The parameter `safe` is used to specify whether using array in concurrent-safety, // which is false in default. func NewSortedStrArraySize(cap int, safe ...bool) *SortedStrArray { return &SortedStrArray{ @@ -57,8 +57,8 @@ func NewSortedStrArraySize(cap int, safe ...bool) *SortedStrArray { } } -// NewSortedStrArrayFrom creates and returns an sorted array with given slice . -// The parameter is used to specify whether using array in concurrent-safety, +// NewSortedStrArrayFrom creates and returns an sorted array with given slice `array`. +// The parameter `safe` is used to specify whether using array in concurrent-safety, // which is false in default. func NewSortedStrArrayFrom(array []string, safe ...bool) *SortedStrArray { a := NewSortedStrArraySize(0, safe...) @@ -67,8 +67,8 @@ func NewSortedStrArrayFrom(array []string, safe ...bool) *SortedStrArray { return a } -// NewSortedStrArrayFromCopy creates and returns an sorted array from a copy of given slice . -// The parameter is used to specify whether using array in concurrent-safety, +// NewSortedStrArrayFromCopy creates and returns an sorted array from a copy of given slice `array`. +// The parameter `safe` is used to specify whether using array in concurrent-safety, // which is false in default. func NewSortedStrArrayFromCopy(array []string, safe ...bool) *SortedStrArray { newArray := make([]string, len(array)) @@ -76,7 +76,7 @@ func NewSortedStrArrayFromCopy(array []string, safe ...bool) *SortedStrArray { return NewSortedStrArrayFrom(newArray, safe...) } -// SetArray sets the underlying slice array with the given . +// SetArray sets the underlying slice array with the given `array`. func (a *SortedStrArray) SetArray(array []string) *SortedStrArray { a.mu.Lock() defer a.mu.Unlock() @@ -85,8 +85,15 @@ func (a *SortedStrArray) SetArray(array []string) *SortedStrArray { return a } +// At returns the value by the specified index. +// If the given `index` is out of range of the array, it returns an empty string. +func (a *SortedStrArray) At(index int) (value string) { + value, _ = a.Get(index) + return +} + // Sort sorts the array in increasing order. -// The parameter controls whether sort +// The parameter `reverse` controls whether sort // in increasing order(default) or decreasing order. func (a *SortedStrArray) Sort() *SortedStrArray { a.mu.Lock() @@ -128,7 +135,7 @@ func (a *SortedStrArray) Append(values ...string) *SortedStrArray { } // Get returns the value by the specified index. -// If the given is out of range of the array, the is false. +// If the given `index` is out of range of the array, the `found` is false. func (a *SortedStrArray) Get(index int) (value string, found bool) { a.mu.RLock() defer a.mu.RUnlock() @@ -139,7 +146,7 @@ func (a *SortedStrArray) Get(index int) (value string, found bool) { } // Remove removes an item by index. -// If the given is out of range of the array, the is false. +// If the given `index` is out of range of the array, the `found` is false. func (a *SortedStrArray) Remove(index int) (value string, found bool) { a.mu.Lock() defer a.mu.Unlock() @@ -180,7 +187,7 @@ func (a *SortedStrArray) RemoveValue(value string) bool { } // PopLeft pops and returns an item from the beginning of array. -// Note that if the array is empty, the is false. +// Note that if the array is empty, the `found` is false. func (a *SortedStrArray) PopLeft() (value string, found bool) { a.mu.Lock() defer a.mu.Unlock() @@ -193,7 +200,7 @@ func (a *SortedStrArray) PopLeft() (value string, found bool) { } // PopRight pops and returns an item from the end of array. -// Note that if the array is empty, the is false. +// Note that if the array is empty, the `found` is false. func (a *SortedStrArray) PopRight() (value string, found bool) { a.mu.Lock() defer a.mu.Unlock() @@ -207,16 +214,16 @@ func (a *SortedStrArray) PopRight() (value string, found bool) { } // PopRand randomly pops and return an item out of array. -// Note that if the array is empty, the is false. +// Note that if the array is empty, the `found` is false. func (a *SortedStrArray) PopRand() (value string, found bool) { a.mu.Lock() defer a.mu.Unlock() return a.doRemoveWithoutLock(grand.Intn(len(a.array))) } -// PopRands randomly pops and returns items out of array. -// If the given is greater than size of the array, it returns all elements of the array. -// Note that if given <= 0 or the array is empty, it returns nil. +// PopRands randomly pops and returns `size` items out of array. +// If the given `size` is greater than size of the array, it returns all elements of the array. +// Note that if given `size` <= 0 or the array is empty, it returns nil. func (a *SortedStrArray) PopRands(size int) []string { a.mu.Lock() defer a.mu.Unlock() @@ -233,9 +240,9 @@ func (a *SortedStrArray) PopRands(size int) []string { return array } -// PopLefts pops and returns items from the beginning of array. -// If the given is greater than size of the array, it returns all elements of the array. -// Note that if given <= 0 or the array is empty, it returns nil. +// PopLefts pops and returns `size` items from the beginning of array. +// If the given `size` is greater than size of the array, it returns all elements of the array. +// Note that if given `size` <= 0 or the array is empty, it returns nil. func (a *SortedStrArray) PopLefts(size int) []string { a.mu.Lock() defer a.mu.Unlock() @@ -252,9 +259,9 @@ func (a *SortedStrArray) PopLefts(size int) []string { return value } -// PopRights pops and returns items from the end of array. -// If the given is greater than size of the array, it returns all elements of the array. -// Note that if given <= 0 or the array is empty, it returns nil. +// PopRights pops and returns `size` items from the end of array. +// If the given `size` is greater than size of the array, it returns all elements of the array. +// Note that if given `size` <= 0 or the array is empty, it returns nil. func (a *SortedStrArray) PopRights(size int) []string { a.mu.Lock() defer a.mu.Unlock() @@ -276,8 +283,8 @@ func (a *SortedStrArray) PopRights(size int) []string { // Notice, if in concurrent-safe usage, it returns a copy of slice; // else a pointer to the underlying data. // -// If is negative, then the offset will start from the end of array. -// If is omitted, then the sequence will have everything from start up +// If `end` is negative, then the offset will start from the end of array. +// If `end` is omitted, then the sequence will have everything from start up // until the end of the array. func (a *SortedStrArray) Range(start int, end ...int) []string { a.mu.RLock() @@ -303,7 +310,7 @@ func (a *SortedStrArray) Range(start int, end ...int) []string { } // SubSlice returns a slice of elements from the array as specified -// by the and parameters. +// by the `offset` and `size` parameters. // If in concurrent safe usage, it returns a copy of the slice; else a pointer. // // If offset is non-negative, the sequence will start at that offset in the array. @@ -418,7 +425,7 @@ func (a *SortedStrArray) ContainsI(value string) bool { return false } -// Search searches array by , returns the index of , +// Search searches array by `value`, returns the index of `value`, // or returns -1 if not exists. func (a *SortedStrArray) Search(value string) (index int) { if i, r := a.binSearch(value, true); r == 0 { @@ -429,9 +436,9 @@ func (a *SortedStrArray) Search(value string) (index int) { // Binary search. // It returns the last compared index and the result. -// If equals to 0, it means the value at is equals to . -// If lesser than 0, it means the value at is lesser than . -// If greater than 0, it means the value at is greater than . +// If `result` equals to 0, it means the value at `index` is equals to `value`. +// If `result` lesser than 0, it means the value at `index` is lesser than `value`. +// If `result` greater than 0, it means the value at `index` is greater than `value`. func (a *SortedStrArray) binSearch(value string, lock bool) (index int, result int) { if lock { a.mu.RLock() @@ -511,7 +518,7 @@ func (a *SortedStrArray) Clear() *SortedStrArray { return a } -// LockFunc locks writing by callback function . +// LockFunc locks writing by callback function `f`. func (a *SortedStrArray) LockFunc(f func(array []string)) *SortedStrArray { a.mu.Lock() defer a.mu.Unlock() @@ -519,7 +526,7 @@ func (a *SortedStrArray) LockFunc(f func(array []string)) *SortedStrArray { return a } -// RLockFunc locks reading by callback function . +// RLockFunc locks reading by callback function `f`. func (a *SortedStrArray) RLockFunc(f func(array []string)) *SortedStrArray { a.mu.RLock() defer a.mu.RUnlock() @@ -527,8 +534,8 @@ func (a *SortedStrArray) RLockFunc(f func(array []string)) *SortedStrArray { return a } -// Merge merges into current array. -// The parameter can be any garray or slice type. +// Merge merges `array` into current array. +// The parameter `array` can be any garray or slice type. // The difference between Merge and Append is Append supports only specified slice type, // but Merge supports more parameter types. func (a *SortedStrArray) Merge(array interface{}) *SortedStrArray { @@ -536,7 +543,7 @@ func (a *SortedStrArray) Merge(array interface{}) *SortedStrArray { } // Chunk splits an array into multiple arrays, -// the size of each array is determined by . +// the size of each array is determined by `size`. // The last chunk may contain less than size elements. func (a *SortedStrArray) Chunk(size int) [][]string { if size < 1 { @@ -568,7 +575,7 @@ func (a *SortedStrArray) Rand() (value string, found bool) { return a.array[grand.Intn(len(a.array))], true } -// Rands randomly returns items from array(no deleting). +// Rands randomly returns `size` items from array(no deleting). func (a *SortedStrArray) Rands(size int) []string { a.mu.RLock() defer a.mu.RUnlock() @@ -582,7 +589,7 @@ func (a *SortedStrArray) Rands(size int) []string { return array } -// Join joins array elements with a string . +// Join joins array elements with a string `glue`. func (a *SortedStrArray) Join(glue string) string { a.mu.RLock() defer a.mu.RUnlock() @@ -615,8 +622,8 @@ func (a *SortedStrArray) Iterator(f func(k int, v string) bool) { a.IteratorAsc(f) } -// IteratorAsc iterates the array readonly in ascending order with given callback function . -// If returns true, then it continues iterating; or false to stop. +// IteratorAsc iterates the array readonly in ascending order with given callback function `f`. +// If `f` returns true, then it continues iterating; or false to stop. func (a *SortedStrArray) IteratorAsc(f func(k int, v string) bool) { a.mu.RLock() defer a.mu.RUnlock() @@ -627,8 +634,8 @@ func (a *SortedStrArray) IteratorAsc(f func(k int, v string) bool) { } } -// IteratorDesc iterates the array readonly in descending order with given callback function . -// If returns true, then it continues iterating; or false to stop. +// IteratorDesc iterates the array readonly in descending order with given callback function `f`. +// If `f` returns true, then it continues iterating; or false to stop. func (a *SortedStrArray) IteratorDesc(f func(k int, v string) bool) { a.mu.RLock() defer a.mu.RUnlock() @@ -720,7 +727,7 @@ func (a *SortedStrArray) FilterEmpty() *SortedStrArray { return a } -// Walk applies a user supplied function to every item of array. +// Walk applies a user supplied function `f` to every item of array. func (a *SortedStrArray) Walk(f func(value string) string) *SortedStrArray { a.mu.Lock() defer a.mu.Unlock() diff --git a/container/garray/garray_z_example_any_test.go b/container/garray/garray_z_example_any_test.go index f79fe1adc..fccf99716 100644 --- a/container/garray/garray_z_example_any_test.go +++ b/container/garray/garray_z_example_any_test.go @@ -75,14 +75,14 @@ func ExampleNew() { func ExampleArray_Iterator() { array := garray.NewArrayFrom(g.Slice{"a", "b", "c"}) // Iterator is alias of IteratorAsc, which iterates the array readonly in ascending order - // with given callback function . - // If returns true, then it continues iterating; or false to stop. + // with given callback function `f`. + // If `f` returns true, then it continues iterating; or false to stop. array.Iterator(func(k int, v interface{}) bool { fmt.Println(k, v) return true }) - // IteratorDesc iterates the array readonly in descending order with given callback function . - // If returns true, then it continues iterating; or false to stop. + // IteratorDesc iterates the array readonly in descending order with given callback function `f`. + // If `f` returns true, then it continues iterating; or false to stop. array.IteratorDesc(func(k int, v interface{}) bool { fmt.Println(k, v) return true @@ -150,7 +150,7 @@ func ExampleArray_Chunk() { array := garray.NewFrom(g.Slice{1, 2, 3, 4, 5, 6, 7, 8, 9}) // Chunk splits an array into multiple arrays, - // the size of each array is determined by . + // the size of each array is determined by `size`. // The last chunk may contain less than size elements. fmt.Println(array.Chunk(2)) diff --git a/os/glog/glog.go b/os/glog/glog.go index 089f853f7..a465a5b43 100644 --- a/os/glog/glog.go +++ b/os/glog/glog.go @@ -30,7 +30,7 @@ func init() { SetDebug(defaultDebug) } -// Default returns the default logger. +// DefaultLogger returns the default logger. func DefaultLogger() *Logger { return logger } diff --git a/os/glog/glog_api.go b/os/glog/glog_api.go index 830d6f64f..243a7b993 100644 --- a/os/glog/glog_api.go +++ b/os/glog/glog_api.go @@ -18,6 +18,7 @@ func Printf(format string, v ...interface{}) { logger.Printf(format, v...) } +// Println is alias of Print. // See Print. func Println(v ...interface{}) { logger.Println(v...) diff --git a/os/glog/glog_config.go b/os/glog/glog_config.go index c38454495..6e4402dee 100644 --- a/os/glog/glog_config.go +++ b/os/glog/glog_config.go @@ -148,3 +148,8 @@ func SetLevelPrefixes(prefixes map[int]string) { func GetLevelPrefix(level int) string { return logger.GetLevelPrefix(level) } + +// SetHandlers sets the logging handlers for default logger. +func SetHandlers(handlers ...Handler) { + logger.SetHandlers(handlers...) +} diff --git a/os/glog/glog_logger.go b/os/glog/glog_logger.go index 59d3d4f88..7f4dcbc91 100644 --- a/os/glog/glog_logger.go +++ b/os/glog/glog_logger.go @@ -62,6 +62,7 @@ func New() *Logger { init: gtype.NewBool(), config: DefaultConfig(), } + logger.config.Handlers = []Handler{defaultHandler} return logger } @@ -94,7 +95,7 @@ func (l *Logger) getFilePath(now time.Time) string { } // print prints to defined writer, logging file or passed . -func (l *Logger) print(std io.Writer, lead string, values ...interface{}) { +func (l *Logger) print(ctx context.Context, level int, values ...interface{}) { // Lazy initialize for rotation feature. // It uses atomic reading operation to enhance the performance checking. // It here uses CAP for performance and concurrent safety. @@ -111,69 +112,70 @@ func (l *Logger) print(std io.Writer, lead string, values ...interface{}) { } var ( - now = time.Now() - buffer = bytes.NewBuffer(nil) + now = time.Now() + input = &HandlerInput{ + logger: l, + index: -1, + Ctx: ctx, + Time: now, + Level: level, + } ) if l.config.HeaderPrint { // Time. timeFormat := "" if l.config.Flags&F_TIME_DATE > 0 { - timeFormat += "2006-01-02 " + timeFormat += "2006-01-02" } if l.config.Flags&F_TIME_TIME > 0 { - timeFormat += "15:04:05 " + if timeFormat != "" { + timeFormat += " " + } + timeFormat += "15:04:05" } if l.config.Flags&F_TIME_MILLI > 0 { - timeFormat += "15:04:05.000 " + if timeFormat != "" { + timeFormat += " " + } + timeFormat += "15:04:05.000" } if len(timeFormat) > 0 { - buffer.WriteString(now.Format(timeFormat)) - } - // Lead string. - if len(lead) > 0 { - buffer.WriteString(lead) - if len(values) > 0 { - buffer.WriteByte(' ') - } + input.TimeFormat = now.Format(timeFormat) } + + // Level string. + input.LevelFormat = l.getLevelPrefixWithBrackets(level) + // Caller path and Fn name. if l.config.Flags&(F_FILE_LONG|F_FILE_SHORT|F_CALLER_FN) > 0 { - callerPath := "" callerFnName, path, line := gdebug.CallerWithFilter(pathFilterKey, l.config.StSkip) if l.config.Flags&F_CALLER_FN > 0 { - buffer.WriteString(fmt.Sprintf(`[%s] `, callerFnName)) + input.CallerFunc = fmt.Sprintf(`[%s]`, callerFnName) } if l.config.Flags&F_FILE_LONG > 0 { - callerPath = fmt.Sprintf(`%s:%d: `, path, line) + input.CallerPath = fmt.Sprintf(`%s:%d:`, path, line) } if l.config.Flags&F_FILE_SHORT > 0 { - callerPath = fmt.Sprintf(`%s:%d: `, gfile.Basename(path), line) + input.CallerPath = fmt.Sprintf(`%s:%d:`, gfile.Basename(path), line) } - buffer.WriteString(callerPath) - } // Prefix. if len(l.config.Prefix) > 0 { - buffer.WriteString(l.config.Prefix + " ") + input.Prefix = l.config.Prefix } } // Convert value to string. - var ( - tempStr = "" - valueStr = "" - ) - - if l.ctx != nil { + if ctx != nil { // Tracing values. - spanCtx := trace.SpanContextFromContext(l.ctx) + spanCtx := trace.SpanContextFromContext(ctx) if traceId := spanCtx.TraceID(); traceId.IsValid() { - buffer.WriteString(fmt.Sprintf("{TraceID:%s} ", traceId.String())) + input.CtxStr = "{TraceID:" + traceId.String() + "}" } // Context values. if len(l.config.CtxKeys) > 0 { ctxStr := "" for _, key := range l.config.CtxKeys { - if v := l.ctx.Value(key); v != nil { + if v := ctx.Value(key); v != nil { if ctxStr != "" { ctxStr += ", " } @@ -181,51 +183,52 @@ func (l *Logger) print(std io.Writer, lead string, values ...interface{}) { } } if ctxStr != "" { - buffer.WriteString(fmt.Sprintf("{%s} ", ctxStr)) + input.CtxStr += "{" + ctxStr + "}" } } } - + var tempStr string for _, v := range values { tempStr = gconv.String(v) - if len(valueStr) > 0 { - if valueStr[len(valueStr)-1] == '\n' { + if len(input.Content) > 0 { + if input.Content[len(input.Content)-1] == '\n' { // Remove one blank line(\n\n). if tempStr[0] == '\n' { - valueStr += tempStr[1:] + input.Content += tempStr[1:] } else { - valueStr += tempStr + input.Content += tempStr } } else { - valueStr += " " + tempStr + input.Content += " " + tempStr } } else { - valueStr = tempStr + input.Content = tempStr } } - buffer.WriteString(valueStr + "\n") if l.config.Flags&F_ASYNC > 0 { + input.IsAsync = true err := asyncPool.Add(func() { - l.printToWriter(now, std, buffer) + input.Next() }) if err != nil { intlog.Error(err) } } else { - l.printToWriter(now, std, buffer) + input.Next() } } // printToWriter writes buffer to writer. -func (l *Logger) printToWriter(now time.Time, std io.Writer, buffer *bytes.Buffer) { +func (l *Logger) printToWriter(ctx context.Context, input *HandlerInput) { + buffer := input.Buffer() if l.config.Writer == nil { // Output content to disk file. if l.config.Path != "" { - l.printToFile(now, buffer) + l.printToFile(input.Time, buffer) } // Allow output to stdout? if l.config.StdoutPrint { - if _, err := std.Write(buffer.Bytes()); err != nil { + if _, err := os.Stdout.Write(buffer.Bytes()); err != nil { intlog.Error(err) } } @@ -238,9 +241,9 @@ func (l *Logger) printToWriter(now time.Time, std io.Writer, buffer *bytes.Buffe } // printToFile outputs logging content to disk file. -func (l *Logger) printToFile(now time.Time, buffer *bytes.Buffer) { +func (l *Logger) printToFile(t time.Time, buffer *bytes.Buffer) { var ( - logFilePath = l.getFilePath(now) + logFilePath = l.getFilePath(t) memoryLockKey = "glog.printToFile:" + logFilePath ) gmlock.Lock(memoryLockKey) @@ -249,7 +252,7 @@ func (l *Logger) printToFile(now time.Time, buffer *bytes.Buffer) { // Rotation file size checks. if l.config.RotateSize > 0 { if gfile.Size(logFilePath) > l.config.RotateSize { - l.rotateFileBySize(now) + l.rotateFileBySize(t) } } // Logging content outputting to disk file. @@ -280,20 +283,29 @@ func (l *Logger) getFilePointer(path string) *gfpool.File { return file } +// getCtx returns the context which is set through chaining operations. +// It returns an empty context if no context set previously. +func (l *Logger) getCtx() context.Context { + if l.ctx != nil { + return l.ctx + } + return context.TODO() +} + // printStd prints content without stack. -func (l *Logger) printStd(lead string, value ...interface{}) { - l.print(os.Stdout, lead, value...) +func (l *Logger) printStd(level int, value ...interface{}) { + l.print(l.getCtx(), level, value...) } // printStd prints content with stack check. -func (l *Logger) printErr(lead string, value ...interface{}) { +func (l *Logger) printErr(level int, value ...interface{}) { if l.config.StStatus == 1 { if s := l.GetStack(); s != "" { value = append(value, "\nStack:\n"+s) } } // In matter of sequence, do not use stderr here, but use the same stdout. - l.print(os.Stdout, lead, value...) + l.print(l.getCtx(), level, value...) } // format formats using fmt.Sprintf. diff --git a/os/glog/glog_logger_api.go b/os/glog/glog_logger_api.go index f7769630d..321da0752 100644 --- a/os/glog/glog_logger_api.go +++ b/os/glog/glog_logger_api.go @@ -14,13 +14,13 @@ import ( // Print prints with newline using fmt.Sprintln. // The parameter can be multiple variables. func (l *Logger) Print(v ...interface{}) { - l.printStd("", v...) + l.printStd(LEVEL_NONE, v...) } // Printf prints with format using fmt.Sprintf. // The parameter can be multiple variables. func (l *Logger) Printf(format string, v ...interface{}) { - l.printStd("", l.format(format, v...)) + l.printStd(LEVEL_NONE, l.format(format, v...)) } // Println is alias of Print. @@ -31,53 +31,53 @@ func (l *Logger) Println(v ...interface{}) { // Fatal prints the logging content with [FATA] header and newline, then exit the current process. func (l *Logger) Fatal(v ...interface{}) { - l.printErr(l.getLevelPrefixWithBrackets(LEVEL_FATA), v...) + l.printErr(LEVEL_FATA, v...) os.Exit(1) } // Fatalf prints the logging content with [FATA] header, custom format and newline, then exit the current process. func (l *Logger) Fatalf(format string, v ...interface{}) { - l.printErr(l.getLevelPrefixWithBrackets(LEVEL_FATA), l.format(format, v...)) + l.printErr(LEVEL_FATA, l.format(format, v...)) os.Exit(1) } // Panic prints the logging content with [PANI] header and newline, then panics. func (l *Logger) Panic(v ...interface{}) { - l.printErr(l.getLevelPrefixWithBrackets(LEVEL_PANI), v...) + l.printErr(LEVEL_PANI, v...) panic(fmt.Sprint(v...)) } // Panicf prints the logging content with [PANI] header, custom format and newline, then panics. func (l *Logger) Panicf(format string, v ...interface{}) { - l.printErr(l.getLevelPrefixWithBrackets(LEVEL_PANI), l.format(format, v...)) + l.printErr(LEVEL_PANI, l.format(format, v...)) panic(l.format(format, v...)) } // Info prints the logging content with [INFO] header and newline. func (l *Logger) Info(v ...interface{}) { if l.checkLevel(LEVEL_INFO) { - l.printStd(l.getLevelPrefixWithBrackets(LEVEL_INFO), v...) + l.printStd(LEVEL_INFO, v...) } } // Infof prints the logging content with [INFO] header, custom format and newline. func (l *Logger) Infof(format string, v ...interface{}) { if l.checkLevel(LEVEL_INFO) { - l.printStd(l.getLevelPrefixWithBrackets(LEVEL_INFO), l.format(format, v...)) + l.printStd(LEVEL_INFO, l.format(format, v...)) } } // Debug prints the logging content with [DEBU] header and newline. func (l *Logger) Debug(v ...interface{}) { if l.checkLevel(LEVEL_DEBU) { - l.printStd(l.getLevelPrefixWithBrackets(LEVEL_DEBU), v...) + l.printStd(LEVEL_DEBU, v...) } } // Debugf prints the logging content with [DEBU] header, custom format and newline. func (l *Logger) Debugf(format string, v ...interface{}) { if l.checkLevel(LEVEL_DEBU) { - l.printStd(l.getLevelPrefixWithBrackets(LEVEL_DEBU), l.format(format, v...)) + l.printStd(LEVEL_DEBU, l.format(format, v...)) } } @@ -85,7 +85,7 @@ func (l *Logger) Debugf(format string, v ...interface{}) { // It also prints caller stack info if stack feature is enabled. func (l *Logger) Notice(v ...interface{}) { if l.checkLevel(LEVEL_NOTI) { - l.printStd(l.getLevelPrefixWithBrackets(LEVEL_NOTI), v...) + l.printStd(LEVEL_NOTI, v...) } } @@ -93,7 +93,7 @@ func (l *Logger) Notice(v ...interface{}) { // It also prints caller stack info if stack feature is enabled. func (l *Logger) Noticef(format string, v ...interface{}) { if l.checkLevel(LEVEL_NOTI) { - l.printStd(l.getLevelPrefixWithBrackets(LEVEL_NOTI), l.format(format, v...)) + l.printStd(LEVEL_NOTI, l.format(format, v...)) } } @@ -101,7 +101,7 @@ func (l *Logger) Noticef(format string, v ...interface{}) { // It also prints caller stack info if stack feature is enabled. func (l *Logger) Warning(v ...interface{}) { if l.checkLevel(LEVEL_WARN) { - l.printStd(l.getLevelPrefixWithBrackets(LEVEL_WARN), v...) + l.printStd(LEVEL_WARN, v...) } } @@ -109,7 +109,7 @@ func (l *Logger) Warning(v ...interface{}) { // It also prints caller stack info if stack feature is enabled. func (l *Logger) Warningf(format string, v ...interface{}) { if l.checkLevel(LEVEL_WARN) { - l.printStd(l.getLevelPrefixWithBrackets(LEVEL_WARN), l.format(format, v...)) + l.printStd(LEVEL_WARN, l.format(format, v...)) } } @@ -117,7 +117,7 @@ func (l *Logger) Warningf(format string, v ...interface{}) { // It also prints caller stack info if stack feature is enabled. func (l *Logger) Error(v ...interface{}) { if l.checkLevel(LEVEL_ERRO) { - l.printErr(l.getLevelPrefixWithBrackets(LEVEL_ERRO), v...) + l.printErr(LEVEL_ERRO, v...) } } @@ -125,7 +125,7 @@ func (l *Logger) Error(v ...interface{}) { // It also prints caller stack info if stack feature is enabled. func (l *Logger) Errorf(format string, v ...interface{}) { if l.checkLevel(LEVEL_ERRO) { - l.printErr(l.getLevelPrefixWithBrackets(LEVEL_ERRO), l.format(format, v...)) + l.printErr(LEVEL_ERRO, l.format(format, v...)) } } @@ -133,7 +133,7 @@ func (l *Logger) Errorf(format string, v ...interface{}) { // It also prints caller stack info if stack feature is enabled. func (l *Logger) Critical(v ...interface{}) { if l.checkLevel(LEVEL_CRIT) { - l.printErr(l.getLevelPrefixWithBrackets(LEVEL_CRIT), v...) + l.printErr(LEVEL_CRIT, v...) } } @@ -141,7 +141,7 @@ func (l *Logger) Critical(v ...interface{}) { // It also prints caller stack info if stack feature is enabled. func (l *Logger) Criticalf(format string, v ...interface{}) { if l.checkLevel(LEVEL_CRIT) { - l.printErr(l.getLevelPrefixWithBrackets(LEVEL_CRIT), l.format(format, v...)) + l.printErr(LEVEL_CRIT, l.format(format, v...)) } } diff --git a/os/glog/glog_logger_config.go b/os/glog/glog_logger_config.go index f28e6862a..6b00a6afd 100644 --- a/os/glog/glog_logger_config.go +++ b/os/glog/glog_logger_config.go @@ -22,6 +22,7 @@ import ( // Config is the configuration object for logger. type Config struct { + Handlers []Handler `json:"-"` // Logger handlers which implement feature similar as middleware. Writer io.Writer `json:"-"` // Customized io.Writer. Flags int `json:"flags"` // Extra flags for logging output features. Path string `json:"path"` // Logging directory path. @@ -246,3 +247,8 @@ func (l *Logger) SetHeaderPrint(enabled bool) { func (l *Logger) SetPrefix(prefix string) { l.config.Prefix = prefix } + +// SetHandlers sets the logging handlers for current logger. +func (l *Logger) SetHandlers(handlers ...Handler) { + l.config.Handlers = append(handlers, defaultHandler) +} diff --git a/os/glog/glog_logger_handler.go b/os/glog/glog_logger_handler.go new file mode 100644 index 000000000..1991cd547 --- /dev/null +++ b/os/glog/glog_logger_handler.go @@ -0,0 +1,78 @@ +// 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 glog + +import ( + "bytes" + "context" + "time" +) + +type Handler func(ctx context.Context, input *HandlerInput) + +type HandlerInput struct { + logger *Logger + index int + Ctx context.Context + Time time.Time + TimeFormat string + Level int + LevelFormat string + CallerFunc string + CallerPath string + CtxStr string + Prefix string + Content string + IsAsync bool +} + +// defaultHandler is the default handler for logger. +func defaultHandler(ctx context.Context, input *HandlerInput) { + input.logger.printToWriter(ctx, input) +} + +func (i *HandlerInput) addStringToBuffer(buffer *bytes.Buffer, s string) { + if buffer.Len() > 0 { + buffer.WriteByte(' ') + } + buffer.WriteString(s) +} + +func (i *HandlerInput) Buffer() *bytes.Buffer { + buffer := bytes.NewBuffer(nil) + buffer.WriteString(i.TimeFormat) + if i.LevelFormat != "" { + i.addStringToBuffer(buffer, i.LevelFormat) + } + if i.CallerFunc != "" { + i.addStringToBuffer(buffer, i.CallerFunc) + } + if i.CallerPath != "" { + i.addStringToBuffer(buffer, i.CallerPath) + } + if i.Prefix != "" { + i.addStringToBuffer(buffer, i.Prefix) + } + if i.CtxStr != "" { + i.addStringToBuffer(buffer, i.CtxStr) + } + if i.Content != "" { + i.addStringToBuffer(buffer, i.Content) + } + return buffer +} + +func (i *HandlerInput) String() string { + return i.Buffer().String() +} + +func (i *HandlerInput) Next() { + if len(i.logger.config.Handlers)-1 > i.index { + i.index++ + i.logger.config.Handlers[i.index](i.Ctx, i) + } +} diff --git a/os/glog/glog_logger_level.go b/os/glog/glog_logger_level.go index f9b5c28ed..a756bc6f8 100644 --- a/os/glog/glog_logger_level.go +++ b/os/glog/glog_logger_level.go @@ -18,6 +18,7 @@ const ( LEVEL_ALL = LEVEL_DEBU | LEVEL_INFO | LEVEL_NOTI | LEVEL_WARN | LEVEL_ERRO | LEVEL_CRIT LEVEL_DEV = LEVEL_ALL LEVEL_PROD = LEVEL_WARN | LEVEL_ERRO | LEVEL_CRIT + LEVEL_NONE = 0 LEVEL_DEBU = 1 << iota // 8 LEVEL_INFO // 16 LEVEL_NOTI // 32 diff --git a/os/glog/glog_z_unit_handler_test.go b/os/glog/glog_z_unit_handler_test.go new file mode 100644 index 000000000..70acc0f5c --- /dev/null +++ b/os/glog/glog_z_unit_handler_test.go @@ -0,0 +1,80 @@ +// 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 glog_test + +import ( + "bytes" + "context" + "github.com/gogf/gf/container/garray" + "github.com/gogf/gf/os/glog" + "github.com/gogf/gf/test/gtest" + "github.com/gogf/gf/text/gstr" + "testing" +) + +var arrayForHandlerTest1 = garray.NewStrArray() + +func customHandler1(ctx context.Context, input *glog.HandlerInput) { + arrayForHandlerTest1.Append(input.String()) + input.Next() +} + +func TestLogger_SetHandlers1(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + w := bytes.NewBuffer(nil) + l := glog.NewWithWriter(w) + l.SetHandlers(customHandler1) + l.SetCtxKeys("Trace-Id", "Span-Id", "Test") + ctx := context.WithValue(context.Background(), "Trace-Id", "1234567890") + ctx = context.WithValue(ctx, "Span-Id", "abcdefg") + + l.Ctx(ctx).Print(1, 2, 3) + t.Assert(gstr.Count(w.String(), "Trace-Id"), 1) + t.Assert(gstr.Count(w.String(), "1234567890"), 1) + t.Assert(gstr.Count(w.String(), "Span-Id"), 1) + t.Assert(gstr.Count(w.String(), "abcdefg"), 1) + t.Assert(gstr.Count(w.String(), "1 2 3"), 1) + + t.Assert(arrayForHandlerTest1.Len(), 1) + t.Assert(gstr.Count(arrayForHandlerTest1.At(0), "Trace-Id"), 1) + t.Assert(gstr.Count(arrayForHandlerTest1.At(0), "1234567890"), 1) + t.Assert(gstr.Count(arrayForHandlerTest1.At(0), "Span-Id"), 1) + t.Assert(gstr.Count(arrayForHandlerTest1.At(0), "abcdefg"), 1) + t.Assert(gstr.Count(arrayForHandlerTest1.At(0), "1 2 3"), 1) + }) +} + +var arrayForHandlerTest2 = garray.NewStrArray() + +func customHandler2(ctx context.Context, input *glog.HandlerInput) { + arrayForHandlerTest2.Append(input.String()) +} + +func TestLogger_SetHandlers2(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + w := bytes.NewBuffer(nil) + l := glog.NewWithWriter(w) + l.SetHandlers(customHandler2) + l.SetCtxKeys("Trace-Id", "Span-Id", "Test") + ctx := context.WithValue(context.Background(), "Trace-Id", "1234567890") + ctx = context.WithValue(ctx, "Span-Id", "abcdefg") + + l.Ctx(ctx).Print(1, 2, 3) + t.Assert(gstr.Count(w.String(), "Trace-Id"), 0) + t.Assert(gstr.Count(w.String(), "1234567890"), 0) + t.Assert(gstr.Count(w.String(), "Span-Id"), 0) + t.Assert(gstr.Count(w.String(), "abcdefg"), 0) + t.Assert(gstr.Count(w.String(), "1 2 3"), 0) + + t.Assert(arrayForHandlerTest2.Len(), 1) + t.Assert(gstr.Count(arrayForHandlerTest2.At(0), "Trace-Id"), 1) + t.Assert(gstr.Count(arrayForHandlerTest2.At(0), "1234567890"), 1) + t.Assert(gstr.Count(arrayForHandlerTest2.At(0), "Span-Id"), 1) + t.Assert(gstr.Count(arrayForHandlerTest2.At(0), "abcdefg"), 1) + t.Assert(gstr.Count(arrayForHandlerTest2.At(0), "1 2 3"), 1) + }) +}