mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-14 17:52:28 +08:00
Compare commits
6 Commits
v2.3.2
...
f467658481
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f467658481 | ||
|
|
5c9d0e396e | ||
|
|
8f74460c1b | ||
|
|
d5752499bf | ||
|
|
eb7cf76eae | ||
|
|
4af074d181 |
@@ -903,6 +903,7 @@ import "github.com/duke-git/lancet/v2/maputil"
|
||||
[[play](https://go.dev/play/p/isZZHOsDhFc)]
|
||||
- **<big>GetOrSet</big>** : returns value of the given key or set the given value value if not present.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/maputil.md#GetOrSet)]
|
||||
[[play](https://go.dev/play/p/IVQwO1OkEJC)]
|
||||
- **<big>MapToStruct</big>** : converts map to struct.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/maputil.md#MapToStruct)]
|
||||
[[play](https://go.dev/play/p/7wYyVfX38Dp)]
|
||||
@@ -1209,11 +1210,13 @@ import "github.com/duke-git/lancet/v2/retry"
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/retry.md#BackoffStrategy)]
|
||||
- **<big>RetryWithCustomBackoff</big>** : set abitary custom backoff strategy.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/retry.md#RetryWithCustomBackoff)]
|
||||
[[play](https://go.dev/play/p/jIm_o2vb5Y4)]
|
||||
- **<big>RetryWithLinearBackoff</big>** : set linear strategy backoff.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/retry.md#RetryWithLinearBackoff)]
|
||||
[[play](https://go.dev/play/p/PDet2ZQZwcB)]
|
||||
- **<big>RetryWithExponentialWithJitterBackoff</big>** : set exponential strategy backoff.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/retry.md#RetryWithExponentialWithJitterBackoff)]
|
||||
|
||||
[[play](https://go.dev/play/p/xp1avQmn16X)]
|
||||
|
||||
|
||||
<h3 id="slice"> 18. Slice contains some functions to manipulate slice. <a href="#index">index</a></h3>
|
||||
@@ -1418,6 +1421,7 @@ import "github.com/duke-git/lancet/v2/slice"
|
||||
[[play](https://go.dev/play/p/UR323iZLDpv)]
|
||||
- **<big>UniqueByField</big>** : remove duplicate elements in struct slice by struct field.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#UniqueByField)]
|
||||
[[play](https://go.dev/play/p/6cifcZSPIGu)]
|
||||
- **<big>Union</big>** : creates a slice of unique elements, in order, from all given slices.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#Union)]
|
||||
[[play](https://go.dev/play/p/hfXV1iRIZOf)]
|
||||
|
||||
@@ -902,9 +902,10 @@ import "github.com/duke-git/lancet/v2/maputil"
|
||||
[[play](https://go.dev/play/p/N9qgYg_Ho6f)]
|
||||
- **<big>HasKey</big>** : 检查 map 是否包含某个 key。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/maputil.md#HasKey)]
|
||||
[[play](https://go.dev/play/p/isZZHOsDhFc)]
|
||||
- **<big>GetOrSet</big>** : 返回给定键的值,如果不存在则设置该值。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/maputil.md#GetOrSet)]
|
||||
[[play](https://go.dev/play/p/isZZHOsDhFc)]
|
||||
[[play](https://go.dev/play/p/IVQwO1OkEJC)]
|
||||
- **<big>MapToStruct</big>** : 将map转成struct。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/maputil.md#MapToStruct)]
|
||||
[[play](https://go.dev/play/p/7wYyVfX38Dp)]
|
||||
@@ -1209,10 +1210,13 @@ import "github.com/duke-git/lancet/v2/retry"
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/retry.md#BackoffStrategy)]
|
||||
- **<big>RetryWithCustomBackoff</big>** : 设置自定义退避策略。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/retry.md#RetryWithCustomBackoff)]
|
||||
[[play](https://go.dev/play/p/jIm_o2vb5Y4)]
|
||||
- **<big>RetryWithLinearBackoff</big>** : 设置线性策略退避。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/retry.md#RetryWithLinearBackoff)]
|
||||
[[play](https://go.dev/play/p/PDet2ZQZwcB)]
|
||||
- **<big>RetryWithExponentialWithJitterBackoff</big>** : 设置指数策略退避。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/retry.md#RetryWithExponentialWithJitterBackoff)]
|
||||
[[play](https://go.dev/play/p/xp1avQmn16X)]
|
||||
|
||||
|
||||
|
||||
@@ -1416,8 +1420,9 @@ import "github.com/duke-git/lancet/v2/slice"
|
||||
- **<big>UniqueBy</big>** : 对切片的每个元素调用 iteratee 函数,然后删除重复元素。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#UniqueBy)]
|
||||
[[play](https://go.dev/play/p/UR323iZLDpv)]
|
||||
- **<big>UniqueByField</big>** : 根据struct字段对struct切片去重复
|
||||
- **<big>UniqueByField</big>** : 根据struct字段对struct切片去重复。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#UniqueByField)]
|
||||
[[play](https://go.dev/play/p/6cifcZSPIGu)]
|
||||
- **<big>Union</big>** : 合并多个切片。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#Union)]
|
||||
[[play](https://go.dev/play/p/hfXV1iRIZOf)]
|
||||
|
||||
@@ -49,9 +49,7 @@ func Or[T, U any](a T, b U) bool {
|
||||
// Xor returns true if a or b but not both is truthy.
|
||||
// Play: https://go.dev/play/p/gObZrW7ZbG8
|
||||
func Xor[T, U any](a T, b U) bool {
|
||||
valA := Bool(a)
|
||||
valB := Bool(b)
|
||||
return (valA || valB) && valA != valB
|
||||
return Bool(a) != Bool(b)
|
||||
}
|
||||
|
||||
// Nor returns true if neither a nor b is truthy.
|
||||
@@ -63,9 +61,7 @@ func Nor[T, U any](a T, b U) bool {
|
||||
// Xnor returns true if both a and b or neither a nor b are truthy.
|
||||
// Play: https://go.dev/play/p/OuDB9g51643
|
||||
func Xnor[T, U any](a T, b U) bool {
|
||||
valA := Bool(a)
|
||||
valB := Bool(b)
|
||||
return (valA && valB) || (!valA && !valB)
|
||||
return Bool(a) == Bool(b)
|
||||
}
|
||||
|
||||
// Nand returns false if both a and b are truthy.
|
||||
|
||||
@@ -1497,7 +1497,7 @@ func main() {
|
||||
func GetOrSet[K comparable, V any](m map[K]V, key K, value V) V
|
||||
```
|
||||
|
||||
<b>示例:<span style="float:right;display:inline-block;"></span></b>
|
||||
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/IVQwO1OkEJC)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
@@ -331,7 +331,7 @@ func main() {
|
||||
func RetryWithCustomBackoff(backoffStrategy BackoffStrategy) Option
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/jIm_o2vb5Y4)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -384,7 +384,7 @@ func main() {
|
||||
func RetryWithLinearBackoff(interval time.Duration) Option
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/PDet2ZQZwcB)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -429,7 +429,7 @@ func main() {
|
||||
func RetryWithExponentialWithJitterBackoff(interval time.Duration, base uint64, maxJitter time.Duration) Option
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/xp1avQmn16X)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
@@ -2323,7 +2323,7 @@ func main() {
|
||||
func UniqueByField[T any](slice []T, field string) ([]T, error)
|
||||
```
|
||||
|
||||
<b>示例:<span style="float:right;display:inline-block;"></span></b>
|
||||
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/6cifcZSPIGu)</span></b>
|
||||
|
||||
```go
|
||||
import (
|
||||
|
||||
@@ -1513,7 +1513,7 @@ func main() {
|
||||
func GetOrSet[K comparable, V any](m map[K]V, key K, value V) V
|
||||
```
|
||||
|
||||
<b>Example:<span style="float:right;display:inline-block;"></span></b>
|
||||
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/IVQwO1OkEJC)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
@@ -331,7 +331,7 @@ func main() {
|
||||
func RetryWithCustomBackoff(backoffStrategy BackoffStrategy) Option
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/jIm_o2vb5Y4)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -361,7 +361,7 @@ func main() {
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
err := retry,Retry(increaseNumber, retry.RetryWithCustomBackoff(&ExampleCustomBackoffStrategy{interval: time.Microsecond * 50}))
|
||||
err := retry.Retry(increaseNumber, retry.RetryWithCustomBackoff(&ExampleCustomBackoffStrategy{interval: time.Microsecond * 50}))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -384,7 +384,7 @@ func main() {
|
||||
func RetryWithLinearBackoff(interval time.Duration) Option
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/nk2XRmagfVF)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -429,7 +429,7 @@ func main() {
|
||||
func RetryWithExponentialWithJitterBackoff(interval time.Duration, base uint64, maxJitter time.Duration) Option
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/xp1avQmn16X)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
@@ -2321,7 +2321,7 @@ func main() {
|
||||
func UniqueByField[T any](slice []T, field string) ([]T, error)
|
||||
```
|
||||
|
||||
<b>Example:<span style="float:right;display:inline-block;"></span></b>
|
||||
<b>Example:<span style="float:right;display:inline-block;">[Runs](https://go.dev/play/p/6cifcZSPIGu)</span></b>
|
||||
|
||||
```go
|
||||
import (
|
||||
|
||||
@@ -84,13 +84,26 @@ var (
|
||||
// The precision parameter specifies the number of digits after the decimal point, which defaults to 4.
|
||||
// Play: https://go.dev/play/p/FPXs1suwRcs
|
||||
func DecimalBytes(size float64, precision ...int) string {
|
||||
p := 5
|
||||
pointPosition := 4
|
||||
if len(precision) > 0 {
|
||||
p = precision[0] + 1
|
||||
pointPosition = precision[0]
|
||||
}
|
||||
|
||||
size, unit := calculateByteSize(size, 1000.0, decimalByteUnits)
|
||||
|
||||
return fmt.Sprintf("%.*g%s", p, size, unit)
|
||||
format := fmt.Sprintf("%%.%df", pointPosition)
|
||||
bytes := fmt.Sprintf(format, size)
|
||||
|
||||
for i := len(bytes); i > 0; i-- {
|
||||
s := bytes[i-1]
|
||||
if s != '0' && s != '.' {
|
||||
break
|
||||
}
|
||||
|
||||
bytes = bytes[:i-1]
|
||||
}
|
||||
|
||||
return bytes + unit
|
||||
}
|
||||
|
||||
// BinaryBytes returns a human-readable byte size under binary standard (base 1024)
|
||||
|
||||
@@ -20,6 +20,11 @@ func TestDecimalBytes(t *testing.T) {
|
||||
assert.Equal("3.123PB", DecimalBytes(float64(3.123*UnitPB)))
|
||||
assert.Equal("4.123EB", DecimalBytes(float64(4.123*UnitEB)))
|
||||
assert.Equal("1EB", DecimalBytes(float64(1000*UnitPB)))
|
||||
assert.Equal("62MB", DecimalBytes(61812496, 0))
|
||||
assert.Equal("61.8MB", DecimalBytes(61812496, 1))
|
||||
assert.Equal("401MB", DecimalBytes(401000000))
|
||||
assert.Equal("401MB", DecimalBytes(401000000, 0))
|
||||
assert.Equal("4MB", DecimalBytes(4010000, 0))
|
||||
}
|
||||
|
||||
func TestBinaryBytes(t *testing.T) {
|
||||
|
||||
@@ -438,7 +438,7 @@ func ToSortedSlicesWithComparator[K comparable, V any](m map[K]V, comparator fun
|
||||
}
|
||||
|
||||
// GetOrSet returns value of the given key or set the given value value if not present.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/IVQwO1OkEJC
|
||||
func GetOrSet[K comparable, V any](m map[K]V, key K, value V) V {
|
||||
if v, ok := m[key]; ok {
|
||||
return v
|
||||
|
||||
@@ -45,7 +45,7 @@ func RetryTimes(n uint) Option {
|
||||
}
|
||||
|
||||
// RetryWithCustomBackoff set abitary custom backoff strategy
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/jIm_o2vb5Y4
|
||||
func RetryWithCustomBackoff(backoffStrategy BackoffStrategy) Option {
|
||||
if backoffStrategy == nil {
|
||||
panic("programming error: backoffStrategy must be not nil")
|
||||
@@ -57,7 +57,7 @@ func RetryWithCustomBackoff(backoffStrategy BackoffStrategy) Option {
|
||||
}
|
||||
|
||||
// RetryWithLinearBackoff set linear strategy backoff
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/PDet2ZQZwcB
|
||||
func RetryWithLinearBackoff(interval time.Duration) Option {
|
||||
if interval <= 0 {
|
||||
panic("programming error: retry interval should not be lower or equal to 0")
|
||||
@@ -71,7 +71,7 @@ func RetryWithLinearBackoff(interval time.Duration) Option {
|
||||
}
|
||||
|
||||
// RetryWithExponentialWithJitterBackoff set exponential strategy backoff
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/xp1avQmn16X
|
||||
func RetryWithExponentialWithJitterBackoff(interval time.Duration, base uint64, maxJitter time.Duration) Option {
|
||||
if interval <= 0 {
|
||||
panic("programming error: retry interval should not be lower or equal to 0")
|
||||
|
||||
@@ -797,7 +797,7 @@ func UniqueBy[T comparable](slice []T, iteratee func(item T) T) []T {
|
||||
}
|
||||
|
||||
// UniqueByField remove duplicate elements in struct slice by struct field.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/6cifcZSPIGu
|
||||
func UniqueByField[T any](slice []T, field string) ([]T, error) {
|
||||
seen := map[any]struct{}{}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user