diff --git a/g/container/garray/garray_normal_int.go b/g/container/garray/garray_normal_int.go index 2be98a810..339063ddf 100644 --- a/g/container/garray/garray_normal_int.go +++ b/g/container/garray/garray_normal_int.go @@ -9,11 +9,12 @@ package garray import ( "bytes" "fmt" + "math" + "sort" + "github.com/gogf/gf/g/internal/rwmutex" "github.com/gogf/gf/g/util/gconv" "github.com/gogf/gf/g/util/grand" - "math" - "sort" ) type IntArray struct { @@ -266,31 +267,83 @@ func (a *IntArray) PopRights(size int) []int { // Range picks and returns items by range, like array[start:end]. // Notice, if in concurrent-safe usage, it returns a copy of slice; // else a pointer to the underlying data. -func (a *IntArray) Range(start, end int) []int { +// +// 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 +// until the end of the array. +func (a *IntArray) Range(start int, end ...int) []int { a.mu.RLock() defer a.mu.RUnlock() - length := len(a.array) - if start > length || start > end { + offsetEnd := len(a.array) + if len(end) > 0 && end[0] < offsetEnd { + offsetEnd = end[0] + } + if start > offsetEnd { return nil } if start < 0 { start = 0 } - if end > length { - end = length - } array := ([]int)(nil) if a.mu.IsSafe() { - a.mu.RLock() - defer a.mu.RUnlock() - array = make([]int, end-start) - copy(array, a.array[start:end]) + array = make([]int, offsetEnd-start) + copy(array, a.array[start:offsetEnd]) } else { - array = a.array[start:end] + array = a.array[start:offsetEnd] } return array } +// SubSlice returns a slice of elements from the array as specified +// by the and 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. +// If offset is negative, the sequence will start that far from the end of the array. +// +// If length is given and is positive, then the sequence will have up to that many elements in it. +// If the array is shorter than the length, then only the available array elements will be present. +// If length is given and is negative then the sequence will stop that many elements from the end of the array. +// If it is omitted, then the sequence will have everything from offset up until the end of the array. +// +// Any possibility crossing the left border of array, it will fail. +func (a *IntArray) SubSlice(offset int, length ...int) []int { + a.mu.RLock() + defer a.mu.RUnlock() + size := len(a.array) + if len(length) > 0 { + size = length[0] + } + if offset > len(a.array) { + return nil + } + if offset < 0 { + offset = len(a.array) + offset + if offset < 0 { + return nil + } + } + if size < 0 { + offset += size + size = -size + if offset < 0 { + return nil + } + } + end := offset + size + if end > len(a.array) { + end = len(a.array) + size = len(a.array) - offset + } + if a.mu.IsSafe() { + s := make([]int, size) + copy(s, a.array[offset:]) + return s + } else { + return a.array[offset:end] + } +} + // See PushRight. func (a *IntArray) Append(value ...int) *IntArray { a.mu.Lock() @@ -488,27 +541,6 @@ func (a *IntArray) Pad(size int, value int) *IntArray { return a } -// SubSlice returns a slice of elements from the array as specified -// by the and parameters. -// If in concurrent safe usage, it returns a copy of the slice; else a pointer. -func (a *IntArray) SubSlice(offset, size int) []int { - a.mu.RLock() - defer a.mu.RUnlock() - if offset > len(a.array) { - return nil - } - if offset+size > len(a.array) { - size = len(a.array) - offset - } - if a.mu.IsSafe() { - s := make([]int, size) - copy(s, a.array[offset:]) - return s - } else { - return a.array[offset:] - } -} - // Rand randomly returns one item from array(no deleting). func (a *IntArray) Rand() int { a.mu.RLock() diff --git a/g/container/garray/garray_normal_interface.go b/g/container/garray/garray_normal_interface.go index e95048ef2..c91cd2d97 100644 --- a/g/container/garray/garray_normal_interface.go +++ b/g/container/garray/garray_normal_interface.go @@ -9,11 +9,12 @@ package garray import ( "bytes" "fmt" + "math" + "sort" + "github.com/gogf/gf/g/internal/rwmutex" "github.com/gogf/gf/g/util/gconv" "github.com/gogf/gf/g/util/grand" - "math" - "sort" ) type Array struct { @@ -262,31 +263,83 @@ func (a *Array) PopRights(size int) []interface{} { // Range picks and returns items by range, like array[start:end]. // Notice, if in concurrent-safe usage, it returns a copy of slice; // else a pointer to the underlying data. -func (a *Array) Range(start, end int) []interface{} { +// +// 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 +// until the end of the array. +func (a *Array) Range(start int, end ...int) []interface{} { a.mu.RLock() defer a.mu.RUnlock() - length := len(a.array) - if start > length || start > end { + offsetEnd := len(a.array) + if len(end) > 0 && end[0] < offsetEnd { + offsetEnd = end[0] + } + if start > offsetEnd { return nil } if start < 0 { start = 0 } - if end > length { - end = length - } array := ([]interface{})(nil) if a.mu.IsSafe() { - a.mu.RLock() - defer a.mu.RUnlock() - array = make([]interface{}, end-start) - copy(array, a.array[start:end]) + array = make([]interface{}, offsetEnd-start) + copy(array, a.array[start:offsetEnd]) } else { - array = a.array[start:end] + array = a.array[start:offsetEnd] } return array } +// SubSlice returns a slice of elements from the array as specified +// by the and 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. +// If offset is negative, the sequence will start that far from the end of the array. +// +// If length is given and is positive, then the sequence will have up to that many elements in it. +// If the array is shorter than the length, then only the available array elements will be present. +// If length is given and is negative then the sequence will stop that many elements from the end of the array. +// If it is omitted, then the sequence will have everything from offset up until the end of the array. +// +// Any possibility crossing the left border of array, it will fail. +func (a *Array) SubSlice(offset int, length ...int) []interface{} { + a.mu.RLock() + defer a.mu.RUnlock() + size := len(a.array) + if len(length) > 0 { + size = length[0] + } + if offset > len(a.array) { + return nil + } + if offset < 0 { + offset = len(a.array) + offset + if offset < 0 { + return nil + } + } + if size < 0 { + offset += size + size = -size + if offset < 0 { + return nil + } + } + end := offset + size + if end > len(a.array) { + end = len(a.array) + size = len(a.array) - offset + } + if a.mu.IsSafe() { + s := make([]interface{}, size) + copy(s, a.array[offset:]) + return s + } else { + return a.array[offset:end] + } +} + // See PushRight. func (a *Array) Append(value ...interface{}) *Array { a.PushRight(value...) @@ -482,27 +535,6 @@ func (a *Array) Pad(size int, val interface{}) *Array { return a } -// SubSlice returns a slice of elements from the array as specified -// by the and parameters. -// If in concurrent safe usage, it returns a copy of the slice; else a pointer. -func (a *Array) SubSlice(offset, size int) []interface{} { - a.mu.RLock() - defer a.mu.RUnlock() - if offset > len(a.array) { - return nil - } - if offset+size > len(a.array) { - size = len(a.array) - offset - } - if a.mu.IsSafe() { - s := make([]interface{}, size) - copy(s, a.array[offset:]) - return s - } else { - return a.array[offset:] - } -} - // Rand randomly returns one item from array(no deleting). func (a *Array) Rand() interface{} { a.mu.RLock() diff --git a/g/container/garray/garray_normal_string.go b/g/container/garray/garray_normal_string.go index 702ecda52..bfc61092e 100644 --- a/g/container/garray/garray_normal_string.go +++ b/g/container/garray/garray_normal_string.go @@ -9,12 +9,13 @@ package garray import ( "bytes" "fmt" - "github.com/gogf/gf/g/internal/rwmutex" - "github.com/gogf/gf/g/util/gconv" - "github.com/gogf/gf/g/util/grand" "math" "sort" "strings" + + "github.com/gogf/gf/g/internal/rwmutex" + "github.com/gogf/gf/g/util/gconv" + "github.com/gogf/gf/g/util/grand" ) type StringArray struct { @@ -267,31 +268,83 @@ func (a *StringArray) PopRights(size int) []string { // Range picks and returns items by range, like array[start:end]. // Notice, if in concurrent-safe usage, it returns a copy of slice; // else a pointer to the underlying data. -func (a *StringArray) Range(start, end int) []string { +// +// 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 +// until the end of the array. +func (a *StringArray) Range(start int, end ...int) []string { a.mu.RLock() defer a.mu.RUnlock() - length := len(a.array) - if start > length || start > end { + offsetEnd := len(a.array) + if len(end) > 0 && end[0] < offsetEnd { + offsetEnd = end[0] + } + if start > offsetEnd { return nil } if start < 0 { start = 0 } - if end > length { - end = length - } array := ([]string)(nil) if a.mu.IsSafe() { - a.mu.RLock() - defer a.mu.RUnlock() - array = make([]string, end-start) - copy(array, a.array[start:end]) + array = make([]string, offsetEnd-start) + copy(array, a.array[start:offsetEnd]) } else { - array = a.array[start:end] + array = a.array[start:offsetEnd] } return array } +// SubSlice returns a slice of elements from the array as specified +// by the and 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. +// If offset is negative, the sequence will start that far from the end of the array. +// +// If length is given and is positive, then the sequence will have up to that many elements in it. +// If the array is shorter than the length, then only the available array elements will be present. +// If length is given and is negative then the sequence will stop that many elements from the end of the array. +// If it is omitted, then the sequence will have everything from offset up until the end of the array. +// +// Any possibility crossing the left border of array, it will fail. +func (a *StringArray) SubSlice(offset int, length ...int) []string { + a.mu.RLock() + defer a.mu.RUnlock() + size := len(a.array) + if len(length) > 0 { + size = length[0] + } + if offset > len(a.array) { + return nil + } + if offset < 0 { + offset = len(a.array) + offset + if offset < 0 { + return nil + } + } + if size < 0 { + offset += size + size = -size + if offset < 0 { + return nil + } + } + end := offset + size + if end > len(a.array) { + end = len(a.array) + size = len(a.array) - offset + } + if a.mu.IsSafe() { + s := make([]string, size) + copy(s, a.array[offset:]) + return s + } else { + return a.array[offset:end] + } +} + // See PushRight. func (a *StringArray) Append(value ...string) *StringArray { a.mu.Lock() @@ -488,27 +541,6 @@ func (a *StringArray) Pad(size int, value string) *StringArray { return a } -// SubSlice returns a slice of elements from the array as specified -// by the and parameters. -// If in concurrent safe usage, it returns a copy of the slice; else a pointer. -func (a *StringArray) SubSlice(offset, size int) []string { - a.mu.RLock() - defer a.mu.RUnlock() - if offset > len(a.array) { - return nil - } - if offset+size > len(a.array) { - size = len(a.array) - offset - } - if a.mu.IsSafe() { - s := make([]string, size) - copy(s, a.array[offset:]) - return s - } else { - return a.array[offset:] - } -} - // Rand randomly returns one item from array(no deleting). func (a *StringArray) Rand() string { a.mu.RLock() diff --git a/g/container/garray/garray_sorted_int.go b/g/container/garray/garray_sorted_int.go index e7f792479..8fcd9a8e7 100644 --- a/g/container/garray/garray_sorted_int.go +++ b/g/container/garray/garray_sorted_int.go @@ -9,12 +9,13 @@ package garray import ( "bytes" "fmt" + "math" + "sort" + "github.com/gogf/gf/g/container/gtype" "github.com/gogf/gf/g/internal/rwmutex" "github.com/gogf/gf/g/util/gconv" "github.com/gogf/gf/g/util/grand" - "math" - "sort" ) // It's using increasing order in default. @@ -216,31 +217,83 @@ func (a *SortedIntArray) PopRights(size int) []int { // Range picks and returns items by range, like array[start:end]. // Notice, if in concurrent-safe usage, it returns a copy of slice; // else a pointer to the underlying data. -func (a *SortedIntArray) Range(start, end int) []int { +// +// 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 +// until the end of the array. +func (a *SortedIntArray) Range(start int, end ...int) []int { a.mu.RLock() defer a.mu.RUnlock() - length := len(a.array) - if start > length || start > end { + offsetEnd := len(a.array) + if len(end) > 0 && end[0] < offsetEnd { + offsetEnd = end[0] + } + if start > offsetEnd { return nil } if start < 0 { start = 0 } - if end > length { - end = length - } array := ([]int)(nil) if a.mu.IsSafe() { - a.mu.RLock() - defer a.mu.RUnlock() - array = make([]int, end-start) - copy(array, a.array[start:end]) + array = make([]int, offsetEnd-start) + copy(array, a.array[start:offsetEnd]) } else { - array = a.array[start:end] + array = a.array[start:offsetEnd] } return array } +// SubSlice returns a slice of elements from the array as specified +// by the and 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. +// If offset is negative, the sequence will start that far from the end of the array. +// +// If length is given and is positive, then the sequence will have up to that many elements in it. +// If the array is shorter than the length, then only the available array elements will be present. +// If length is given and is negative then the sequence will stop that many elements from the end of the array. +// If it is omitted, then the sequence will have everything from offset up until the end of the array. +// +// Any possibility crossing the left border of array, it will fail. +func (a *SortedIntArray) SubSlice(offset int, length ...int) []int { + a.mu.RLock() + defer a.mu.RUnlock() + size := len(a.array) + if len(length) > 0 { + size = length[0] + } + if offset > len(a.array) { + return nil + } + if offset < 0 { + offset = len(a.array) + offset + if offset < 0 { + return nil + } + } + if size < 0 { + offset += size + size = -size + if offset < 0 { + return nil + } + } + end := offset + size + if end > len(a.array) { + end = len(a.array) + size = len(a.array) - offset + } + if a.mu.IsSafe() { + s := make([]int, size) + copy(s, a.array[offset:]) + return s + } else { + return a.array[offset:end] + } +} + // Len returns the length of array. func (a *SortedIntArray) Len() int { a.mu.RLock() @@ -433,27 +486,6 @@ func (a *SortedIntArray) Chunk(size int) [][]int { return n } -// SubSlice returns a slice of elements from the array as specified -// by the and parameters. -// If in concurrent safe usage, it returns a copy of the slice; else a pointer. -func (a *SortedIntArray) SubSlice(offset, size int) []int { - a.mu.RLock() - defer a.mu.RUnlock() - if offset > len(a.array) { - return nil - } - if offset+size > len(a.array) { - size = len(a.array) - offset - } - if a.mu.IsSafe() { - s := make([]int, size) - copy(s, a.array[offset:]) - return s - } else { - return a.array[offset:] - } -} - // Rand randomly returns one item from array(no deleting). func (a *SortedIntArray) Rand() int { a.mu.RLock() diff --git a/g/container/garray/garray_sorted_interface.go b/g/container/garray/garray_sorted_interface.go index cb18f5933..ea2966fae 100644 --- a/g/container/garray/garray_sorted_interface.go +++ b/g/container/garray/garray_sorted_interface.go @@ -9,12 +9,13 @@ package garray import ( "bytes" "fmt" + "math" + "sort" + "github.com/gogf/gf/g/container/gtype" "github.com/gogf/gf/g/internal/rwmutex" "github.com/gogf/gf/g/util/gconv" "github.com/gogf/gf/g/util/grand" - "math" - "sort" ) // It's using increasing order in default. @@ -217,31 +218,83 @@ func (a *SortedArray) PopRights(size int) []interface{} { // Range picks and returns items by range, like array[start:end]. // Notice, if in concurrent-safe usage, it returns a copy of slice; // else a pointer to the underlying data. -func (a *SortedArray) Range(start, end int) []interface{} { +// +// 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 +// until the end of the array. +func (a *SortedArray) Range(start int, end ...int) []interface{} { a.mu.RLock() defer a.mu.RUnlock() - length := len(a.array) - if start > length || start > end { + offsetEnd := len(a.array) + if len(end) > 0 && end[0] < offsetEnd { + offsetEnd = end[0] + } + if start > offsetEnd { return nil } if start < 0 { start = 0 } - if end > length { - end = length - } array := ([]interface{})(nil) if a.mu.IsSafe() { - a.mu.RLock() - defer a.mu.RUnlock() - array = make([]interface{}, end-start) - copy(array, a.array[start:end]) + array = make([]interface{}, offsetEnd-start) + copy(array, a.array[start:offsetEnd]) } else { - array = a.array[start:end] + array = a.array[start:offsetEnd] } return array } +// SubSlice returns a slice of elements from the array as specified +// by the and 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. +// If offset is negative, the sequence will start that far from the end of the array. +// +// If length is given and is positive, then the sequence will have up to that many elements in it. +// If the array is shorter than the length, then only the available array elements will be present. +// If length is given and is negative then the sequence will stop that many elements from the end of the array. +// If it is omitted, then the sequence will have everything from offset up until the end of the array. +// +// Any possibility crossing the left border of array, it will fail. +func (a *SortedArray) SubSlice(offset int, length ...int) []interface{} { + a.mu.RLock() + defer a.mu.RUnlock() + size := len(a.array) + if len(length) > 0 { + size = length[0] + } + if offset > len(a.array) { + return nil + } + if offset < 0 { + offset = len(a.array) + offset + if offset < 0 { + return nil + } + } + if size < 0 { + offset += size + size = -size + if offset < 0 { + return nil + } + } + end := offset + size + if end > len(a.array) { + end = len(a.array) + size = len(a.array) - offset + } + if a.mu.IsSafe() { + s := make([]interface{}, size) + copy(s, a.array[offset:]) + return s + } else { + return a.array[offset:end] + } +} + // Sum returns the sum of values in an array. func (a *SortedArray) Sum() (sum int) { a.mu.RLock() @@ -434,27 +487,6 @@ func (a *SortedArray) Chunk(size int) [][]interface{} { return n } -// SubSlice returns a slice of elements from the array as specified -// by the and parameters. -// If in concurrent safe usage, it returns a copy of the slice; else a pointer. -func (a *SortedArray) SubSlice(offset, size int) []interface{} { - a.mu.RLock() - defer a.mu.RUnlock() - if offset > len(a.array) { - return nil - } - if offset+size > len(a.array) { - size = len(a.array) - offset - } - if a.mu.IsSafe() { - s := make([]interface{}, size) - copy(s, a.array[offset:]) - return s - } else { - return a.array[offset:] - } -} - // Rand randomly returns one item from array(no deleting). func (a *SortedArray) Rand() interface{} { a.mu.RLock() diff --git a/g/container/garray/garray_sorted_string.go b/g/container/garray/garray_sorted_string.go index 2092d4f18..89e06b43d 100644 --- a/g/container/garray/garray_sorted_string.go +++ b/g/container/garray/garray_sorted_string.go @@ -9,13 +9,14 @@ package garray import ( "bytes" "fmt" + "math" + "sort" + "strings" + "github.com/gogf/gf/g/container/gtype" "github.com/gogf/gf/g/internal/rwmutex" "github.com/gogf/gf/g/util/gconv" "github.com/gogf/gf/g/util/grand" - "math" - "sort" - "strings" ) // It's using increasing order in default. @@ -211,31 +212,83 @@ func (a *SortedStringArray) PopRights(size int) []string { // Range picks and returns items by range, like array[start:end]. // Notice, if in concurrent-safe usage, it returns a copy of slice; // else a pointer to the underlying data. -func (a *SortedStringArray) Range(start, end int) []string { +// +// 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 +// until the end of the array. +func (a *SortedStringArray) Range(start int, end ...int) []string { a.mu.RLock() defer a.mu.RUnlock() - length := len(a.array) - if start > length || start > end { + offsetEnd := len(a.array) + if len(end) > 0 && end[0] < offsetEnd { + offsetEnd = end[0] + } + if start > offsetEnd { return nil } if start < 0 { start = 0 } - if end > length { - end = length - } array := ([]string)(nil) if a.mu.IsSafe() { - a.mu.RLock() - defer a.mu.RUnlock() - array = make([]string, end-start) - copy(array, a.array[start:end]) + array = make([]string, offsetEnd-start) + copy(array, a.array[start:offsetEnd]) } else { - array = a.array[start:end] + array = a.array[start:offsetEnd] } return array } +// SubSlice returns a slice of elements from the array as specified +// by the and 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. +// If offset is negative, the sequence will start that far from the end of the array. +// +// If length is given and is positive, then the sequence will have up to that many elements in it. +// If the array is shorter than the length, then only the available array elements will be present. +// If length is given and is negative then the sequence will stop that many elements from the end of the array. +// If it is omitted, then the sequence will have everything from offset up until the end of the array. +// +// Any possibility crossing the left border of array, it will fail. +func (a *SortedStringArray) SubSlice(offset int, length ...int) []string { + a.mu.RLock() + defer a.mu.RUnlock() + size := len(a.array) + if len(length) > 0 { + size = length[0] + } + if offset > len(a.array) { + return nil + } + if offset < 0 { + offset = len(a.array) + offset + if offset < 0 { + return nil + } + } + if size < 0 { + offset += size + size = -size + if offset < 0 { + return nil + } + } + end := offset + size + if end > len(a.array) { + end = len(a.array) + size = len(a.array) - offset + } + if a.mu.IsSafe() { + s := make([]string, size) + copy(s, a.array[offset:]) + return s + } else { + return a.array[offset:end] + } +} + // Sum returns the sum of values in an array. func (a *SortedStringArray) Sum() (sum int) { a.mu.RLock() @@ -428,27 +481,6 @@ func (a *SortedStringArray) Chunk(size int) [][]string { return n } -// SubSlice returns a slice of elements from the array as specified -// by the and parameters. -// If in concurrent safe usage, it returns a copy of the slice; else a pointer. -func (a *SortedStringArray) SubSlice(offset, size int) []string { - a.mu.RLock() - defer a.mu.RUnlock() - if offset > len(a.array) { - return nil - } - if offset+size > len(a.array) { - size = len(a.array) - offset - } - if a.mu.IsSafe() { - s := make([]string, size) - copy(s, a.array[offset:]) - return s - } else { - return a.array[offset:] - } -} - // Rand randomly returns one item from array(no deleting). func (a *SortedStringArray) Rand() string { a.mu.RLock() diff --git a/g/container/garray/garray_z_unit_int_test.go b/g/container/garray/garray_z_unit_int_test.go index 6d7e53377..2a65f89f3 100644 --- a/g/container/garray/garray_z_unit_int_test.go +++ b/g/container/garray/garray_z_unit_int_test.go @@ -9,9 +9,10 @@ package garray_test import ( + "testing" + "github.com/gogf/gf/g/container/garray" "github.com/gogf/gf/g/test/gtest" - "testing" ) func Test_IntArray_Basic(t *testing.T) { @@ -100,6 +101,7 @@ func TestIntArray_Range(t *testing.T) { gtest.Assert(array1.Range(0, 1), []int{0}) gtest.Assert(array1.Range(1, 2), []int{1}) gtest.Assert(array1.Range(0, 2), []int{0, 1}) + gtest.Assert(array1.Range(10, 2), nil) gtest.Assert(array1.Range(-1, 10), value1) }) } @@ -151,9 +153,21 @@ func TestIntArray_SubSlice(t *testing.T) { gtest.Case(t, func() { a1 := []int{0, 1, 2, 3, 4, 5, 6} array1 := garray.NewIntArrayFrom(a1) + gtest.Assert(array1.SubSlice(6), []int{6}) + gtest.Assert(array1.SubSlice(5), []int{5, 6}) + gtest.Assert(array1.SubSlice(8), nil) gtest.Assert(array1.SubSlice(0, 2), []int{0, 1}) gtest.Assert(array1.SubSlice(2, 2), []int{2, 3}) gtest.Assert(array1.SubSlice(5, 8), []int{5, 6}) + gtest.Assert(array1.SubSlice(-1, 1), []int{6}) + gtest.Assert(array1.SubSlice(-1, 9), []int{6}) + gtest.Assert(array1.SubSlice(-2, 3), []int{5, 6}) + gtest.Assert(array1.SubSlice(-7, 3), []int{0, 1, 2}) + gtest.Assert(array1.SubSlice(-8, 3), nil) + gtest.Assert(array1.SubSlice(-1, -3), []int{3, 4, 5}) + gtest.Assert(array1.SubSlice(-9, 3), nil) + gtest.Assert(array1.SubSlice(1, -1), []int{0}) + gtest.Assert(array1.SubSlice(1, -3), nil) }) } @@ -435,7 +449,6 @@ func TestSortedIntArray_Chunk(t *testing.T) { array1 := garray.NewSortedIntArrayFrom(a1) ns1 := array1.Chunk(2) //按每几个元素切成一个数组 ns2 := array1.Chunk(-1) - t.Log(ns1) gtest.Assert(len(ns1), 3) gtest.Assert(ns1[0], []int{1, 2}) gtest.Assert(ns1[2], []int{5}) diff --git a/g/net/ghttp/ghttp_server.go b/g/net/ghttp/ghttp_server.go index 98f58c6ca..1f2886ced 100644 --- a/g/net/ghttp/ghttp_server.go +++ b/g/net/ghttp/ghttp_server.go @@ -10,6 +10,14 @@ import ( "bytes" "errors" "fmt" + "net/http" + "os" + "reflect" + "runtime" + "strings" + "sync" + "time" + "github.com/gogf/gf/g/container/garray" "github.com/gogf/gf/g/container/gmap" "github.com/gogf/gf/g/container/gtype" @@ -23,13 +31,6 @@ import ( "github.com/gogf/gf/g/util/gconv" "github.com/gogf/gf/third/github.com/gorilla/websocket" "github.com/gogf/gf/third/github.com/olekukonko/tablewriter" - "net/http" - "os" - "reflect" - "runtime" - "strings" - "sync" - "time" ) type ( @@ -382,15 +383,14 @@ func (s *Server) GetRouteMap() string { } // 阻塞执行监听 -func (s *Server) Run() error { +func (s *Server) Run() { if err := s.Start(); err != nil { - return err + glog.Fatal(err) } // 阻塞等待服务执行完成 <-s.closeChan glog.Printf("%d: all servers shutdown", gproc.Pid()) - return nil } // 阻塞等待所有Web Server停止,常用于多Web Server场景,以及需要将Web Server异步运行的场景 diff --git a/geg/other/test.go b/geg/other/test.go index 520b0ef1e..6ec392dcf 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -1,15 +1,12 @@ package main import ( - "fmt" - "math" - - "github.com/gogf/gf/g/container/gtype" + "github.com/gogf/gf/g/container/garray" + "github.com/gogf/gf/g/test/gtest" ) func main() { - v := gtype.NewInt32(math.MaxInt32) - for i := 1; i < 100; i++ { - fmt.Println(v.Add(int32(i))) - } + a2 := []interface{}{0, 1, 2, 3, 4, 5, 6} + array3 := garray.NewArrayFrom(a2, true) + gtest.Assert(array3.SubSlice(2, 2), []interface{}{2, 3}) } diff --git a/geg/other/test2.go b/geg/other/test2.go index 594daf472..8623d32ca 100644 --- a/geg/other/test2.go +++ b/geg/other/test2.go @@ -1,55 +1,39 @@ package main import ( - "time" - - "github.com/gogf/gf/g/os/gmutex" - - "github.com/gogf/gf/g/os/glog" - - "github.com/gogf/gf/g/container/garray" - "github.com/gogf/gf/g/test/gtest" + "github.com/gogf/gf/g" + "github.com/gogf/gf/g/net/ghttp" ) -func main() { - mu := gmutex.New() - array := garray.New() - glog.Println("step0") - go func() { - mu.LockFunc(func() { - array.Append(1) - time.Sleep(200 * time.Millisecond) - glog.Println("unlocked") - }) - }() - go func() { - time.Sleep(150 * time.Millisecond) - mu.TryRLockFunc(func() { - array.Append(1) - glog.Println("add1") - }) - }() - sum := 1000 - for index := 1; index < sum; index++ { - go func(i int) { - time.Sleep(300 * time.Millisecond) - //fmt.Println(i*10, mu.IsLocked()) - if r := mu.TryRLockFunc(func() { - array.Append(1) - time.Sleep(200 * time.Millisecond) - }); !r { - glog.Println(i, r) - } - }(index) - } - glog.Println("step1") - time.Sleep(100 * time.Millisecond) - glog.Println("step2") - gtest.Assert(array.Len(), 1) - time.Sleep(100 * time.Millisecond) - glog.Println("step3") - gtest.Assert(array.Len(), 1) - time.Sleep(1000 * time.Millisecond) - gtest.Assert(array.Len(), sum) +type Schedule struct{} +type Task struct{} + +func (c *Schedule) ListDir(r *ghttp.Request) { + r.Response.Writeln("ListDir") +} + +func (c *Task) Add(r *ghttp.Request) { + r.Response.Writeln("Add") +} + +func (c *Task) Task(r *ghttp.Request) { + r.Response.Writeln("Task") +} + +// 实现权限校验 +// 通过事件回调,类似于中间件机制,但是可控制的粒度更细,可以精准注册到路由规则 +func AuthHookHandler(r *ghttp.Request) { + // 如果权限校验失败,调用 r.ExitAll() 退出执行流程 +} + +func main() { + s := g.Server() + s.Group("/schedule").Bind([]ghttp.GroupItem{ + {"ALL", "*", AuthHookHandler, ghttp.HOOK_BEFORE_SERVE}, + {"POST", "/schedule", new(Schedule)}, + {"POST", "/task", new(Task)}, + }) + s.SetPort(8199) + s.Run() }