diff --git a/zarray/slice.go b/zarray/slice.go index 463a9fd..e73b7c6 100644 --- a/zarray/slice.go +++ b/zarray/slice.go @@ -9,6 +9,13 @@ import ( "github.com/sohaha/zlsgo/zstring" ) +// CopySlice copy a slice +func CopySlice[T any](l []T) []T { + nl := make([]T, len(l)) + copy(nl, l) + return nl +} + // Rand A random eents func Rand[T any](collection []T) T { l := len(collection) @@ -16,6 +23,7 @@ func Rand[T any](collection []T) T { var zero T return zero } + i := zstring.RandInt(0, l-1) return collection[i] } @@ -33,10 +41,8 @@ func Map[T any, R any](collection []T, iteratee func(int, T) R) []R { // Shuffle creates a slice of shuffled values func Shuffle[T any](collection []T) []T { - l := len(collection) - n := make([]T, l) - copy(n, collection) - rand.Shuffle(l, func(i, j int) { + n := CopySlice(collection) + rand.Shuffle(len(n), func(i, j int) { n[i], n[j] = n[j], n[i] }) @@ -45,9 +51,8 @@ func Shuffle[T any](collection []T) []T { // Reverse creates a slice of reversed values func Reverse[T any](collection []T) []T { - l := len(collection) - n := make([]T, l) - copy(n, collection) + n := CopySlice(collection) + l := len(n) for i := 0; i < l/2; i++ { n[i], n[l-i-1] = n[l-i-1], n[i] } @@ -57,15 +62,18 @@ func Reverse[T any](collection []T) []T { // Filter iterates over eents of collection func Filter[T any](slice []T, predicate func(index int, item T) bool) []T { - l := len(slice) - res := make([]T, 0, l) - for i := 0; i < l; i++ { - v := slice[i] - if predicate(i, v) { - res = append(res, v) + slice = CopySlice(slice) + + j := 0 + for i := range slice { + if !predicate(i, slice[i]) { + continue } + slice[j] = slice[i] + j++ } - return res + + return slice[:j:j] } // Contains returns true if an eent is present in a collection @@ -93,19 +101,15 @@ func Find[T any](collection []T, predicate func(index int, item T) bool) (res T, // Unique returns a duplicate-free version of an array func Unique[T comparable](collection []T) []T { - res := make([]T, 0, len(collection)) repeat := make(map[T]struct{}, len(collection)) - for _, item := range collection { + return Filter(collection, func(_ int, item T) bool { if _, ok := repeat[item]; ok { - continue + return false } - repeat[item] = struct{}{} - res = append(res, item) - } - - return res + return true + }) } func Diff[T comparable](list1 []T, list2 []T) ([]T, []T) { diff --git a/znet/gzip/gzip.go b/znet/gzip/gzip.go index 23bcc99..771c83b 100644 --- a/znet/gzip/gzip.go +++ b/znet/gzip/gzip.go @@ -27,7 +27,6 @@ func New(conf Config) znet.HandlerFunc { } else { c.Next() p := c.PrevContent() - if len(p.Content) < conf.MinContentLength { return } diff --git a/znet/render.go b/znet/render.go index e7fb8a1..9e7fb66 100644 --- a/znet/render.go +++ b/znet/render.go @@ -72,10 +72,12 @@ var ( ) func (c *Context) renderProcessing(code int32, r render) { - if c.stopHandle.Load() && c.prevData.Code.Load() != 0 { - return + // if c.stopHandle.Load() && c.prevData.Code.Load() != 0 { + // return + // } + if code != 0 { + c.prevData.Code.Store(code) } - c.prevData.Code.Store(code) c.mu.Lock() c.render = r c.mu.Unlock() @@ -254,6 +256,10 @@ func (c *Context) Abort(code ...int32) { } } +func (c *Context) IsAbort() bool { + return c.stopHandle.Load() +} + // Redirect Redirect func (c *Context) Redirect(link string, statusCode ...int32) { c.Writer.Header().Set("Location", c.CompletionLink(link)) diff --git a/znet/web_test.go b/znet/web_test.go index 0906f95..a889f6e 100644 --- a/znet/web_test.go +++ b/znet/web_test.go @@ -417,6 +417,10 @@ func TestPost(tt *testing.T) { w = newRequest(r, "POST", "/Post2", "/Post2", func(c *Context) { c.String(200, "ok") + }, func(c *Context) { + T.Equal(false, c.IsAbort()) + c.Next() + T.Equal(true, c.IsAbort()) }, func(c *Context) { c.Abort(222) diff --git a/ztime/cron/cron_test.go b/ztime/cron/cron_test.go index bb1ccda..e484334 100644 --- a/ztime/cron/cron_test.go +++ b/ztime/cron/cron_test.go @@ -71,7 +71,7 @@ func TestRun(tt *testing.T) { t.Equal(true, time.Now().UnixNano() > now.UnixNano()) g.Done() }) - cron.Run() + cron.Run(false) g.Wait() cron.Stop() ii := atomic.LoadInt64(&i) diff --git a/zutil/options.go b/zutil/options.go new file mode 100644 index 0000000..271d40a --- /dev/null +++ b/zutil/options.go @@ -0,0 +1,12 @@ +//go:build go1.18 +// +build go1.18 + +package zutil + +// Optional Optional parameter +func Optional[T interface{}](o T, fn ...func(*T)) T { + for _, f := range fn { + f(&o) + } + return o +} diff --git a/zutil/options_test.go b/zutil/options_test.go new file mode 100644 index 0000000..4c864a2 --- /dev/null +++ b/zutil/options_test.go @@ -0,0 +1,33 @@ +//go:build go1.18 +// +build go1.18 + +package zutil_test + +import ( + "testing" + + "github.com/sohaha/zlsgo" + "github.com/sohaha/zlsgo/zutil" +) + +func TestOptional(t *testing.T) { + tt := zlsgo.NewTest(t) + + o := zutil.Optional(TestSt{Name: "test"}) + tt.Equal("test", o.Name) + tt.Equal(0, o.I) + + o = zutil.Optional(TestSt{Name: "test2"}, func(o *TestSt) { + o.I = 1 + }, func(ts *TestSt) { + ts.I = ts.I + 1 + }) + tt.Equal("test2", o.Name) + tt.Equal(2, o.I) + + o2 := zutil.Optional(&TestSt{Name: "test"}, func(ts **TestSt) { + (*ts).I = 1 + }) + tt.Equal("test", o2.Name) + tt.Equal(1, o2.I) +}