mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-05 05:12:26 +08:00
Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9cd9d1aeb5 | ||
|
|
71b27c0aa9 | ||
|
|
09a379ec6d | ||
|
|
b4b9b03835 | ||
|
|
48c7794b01 | ||
|
|
8e3911833d | ||
|
|
ebe494051b | ||
|
|
c35bda6a65 | ||
|
|
1fe4cdc429 | ||
|
|
6a79e322e3 | ||
|
|
17e8d2bb6d | ||
|
|
325be0d6a1 | ||
|
|
ea0f96a8c0 | ||
|
|
82cbb54787 | ||
|
|
585d33cafa | ||
|
|
bc4cf35e15 | ||
|
|
a3bc20af1d | ||
|
|
61338b6b46 | ||
|
|
bc3c080ac3 | ||
|
|
d3fab15af3 | ||
|
|
6e3e411d46 | ||
|
|
f976941e36 | ||
|
|
4c5524354c | ||
|
|
2c6e9a3fb9 | ||
|
|
5f2c3edff4 | ||
|
|
b422d98702 | ||
|
|
6f27e0bfbf | ||
|
|
ce3b6b461e | ||
|
|
0d6ad4f0d2 | ||
|
|
c875a7f8b8 | ||
|
|
0c62d117a1 | ||
|
|
c260ce493d | ||
|
|
9ffe96d3ef | ||
|
|
d4bba76dc8 | ||
|
|
adaa3ebc43 | ||
|
|
61d38ae3b8 | ||
|
|
c85d910044 |
21
README.md
21
README.md
@@ -1,10 +1,10 @@
|
||||
<div align=center>
|
||||
<a href="https://uvdream.github.io/lancet-docs/en/"><img src="./logo.png" width="200" height="200"/></a>
|
||||
<img src="./logo.png" width="200" height="200"/>
|
||||
|
||||
<br/>
|
||||
|
||||

|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://pkg.go.dev/github.com/duke-git/lancet/v2)
|
||||
[](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
|
||||
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
||||
@@ -113,6 +113,7 @@ import "github.com/duke-git/lancet/v2/algorithm"
|
||||
[[play](https://go.dev/play/p/Anozfr8ZLH3)]
|
||||
- **<big>LinearSearch</big>** : returns the index of target in slice base on equal function.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#LinearSearch)]
|
||||
[[play](https://go.dev/play/p/IsS7rgn5s3x)]
|
||||
- **<big>LRUCache</big>** : implements memory cache with lru algorithm.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#LRUCache)]
|
||||
[[play](https://go.dev/play/p/-EZjgOURufP)]
|
||||
@@ -127,24 +128,34 @@ import "github.com/duke-git/lancet/v2/concurrency"
|
||||
|
||||
- **<big>NewChannel</big>** : create a Channel pointer instance.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#NewChannel)]
|
||||
[[play](https://go.dev/play/p/7aB4KyMMp9A)]
|
||||
- **<big>Bridge</big>** : link multiply channels into one channel.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/Bridge.md#NewChannel)]
|
||||
[[play](https://go.dev/play/p/qmWSy1NVF-Y)]
|
||||
- **<big>FanIn</big>** : merge multiple channels into one channel.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#FanIn)]
|
||||
[[play](https://go.dev/play/p/2VYFMexEvTm)]
|
||||
- **<big>Generate</big>** : creates a channel, then put values into the channel.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#Generate)]
|
||||
[[play](https://go.dev/play/p/7aB4KyMMp9A)]
|
||||
- **<big>Or</big>** : read one or more channels into one channel, will close when any readin channel is closed.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#Or)]
|
||||
[[play](https://go.dev/play/p/Wqz9rwioPww)]
|
||||
- **<big>OrDone</big>** : read a channel into another channel, will close until cancel context.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#OrDone)]
|
||||
[[play](https://go.dev/play/p/lm_GoS6aDjo)]
|
||||
- **<big>Repeat</big>** : create channel, put values into the channel repeatly until cancel the context.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#Repeat)]
|
||||
[[play](https://go.dev/play/p/k5N_ALVmYjE)]
|
||||
- **<big>RepeatFn</big>** : create a channel, excutes fn repeatly, and put the result into the channel, until close context.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#RepeatFn)]
|
||||
[[play](https://go.dev/play/p/4J1zAWttP85)]
|
||||
- **<big>Take</big>** : create a channel whose values are taken from another channel with limit number.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#Take)]
|
||||
[[play](https://go.dev/play/p/9Utt-1pDr2J)]
|
||||
- **<big>Tee</big>** : split one chanel into two channels, until cancel the context.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency.md#Tee)]
|
||||
[[play](https://go.dev/play/p/3TQPKnCirrP)]
|
||||
|
||||
### 3. Condition package contains some functions for conditional judgment. eg. And, Or, TernaryOperator...
|
||||
|
||||
@@ -556,8 +567,10 @@ import "github.com/duke-git/lancet/v2/function"
|
||||
[[play](https://go.dev/play/p/0HqUDIFZ3IL)]
|
||||
- **<big>CurryFn</big>** : make a curry function.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/function.md#CurryFn)]
|
||||
[[play](https://go.dev/play/p/5HopfDwANKX)]
|
||||
- **<big>Compose</big>** : compose the functions from right to left.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/function.md#Compose)]
|
||||
[[play](https://go.dev/play/p/KKfugD4PKYF)]
|
||||
- **<big>Delay</big>** : call the function after delayed time.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/function.md#Delay)]
|
||||
[[play](https://go.dev/play/p/Ivtc2ZE-Tye)]
|
||||
@@ -572,6 +585,8 @@ import "github.com/duke-git/lancet/v2/function"
|
||||
[[play](https://go.dev/play/p/mPdUVvj6HD6)]
|
||||
- **<big>Watcher</big>** : Watcher is used for record code excution time. can start/stop/reset the watch timer. get the elapsed time of function execution.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/function.md#Watcher)]
|
||||
[[play](https://go.dev/play/p/l2yrOpCLd1I)]
|
||||
|
||||
|
||||
### 11. Maputil package includes some functions to manipulate map.
|
||||
|
||||
@@ -640,6 +655,7 @@ import "github.com/duke-git/lancet/v2/mathutil"
|
||||
[[play](https://go.dev/play/p/N9qgYg_Ho6f)]
|
||||
- **<big>Percent</big>** : calculate the percentage of value to total.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Percent)]
|
||||
[[play](https://go.dev/play/p/QQM9B13coSP)]
|
||||
- **<big>RoundToFloat</big>** : round up to n decimal places for float64.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#RoundToFloat)]
|
||||
[[play](https://go.dev/play/p/ghyb528JRJL)]
|
||||
@@ -1000,6 +1016,7 @@ import "github.com/duke-git/lancet/v2/strutil"
|
||||
[[play](https://go.dev/play/p/Us-ySSbWh-3)]
|
||||
- **<big>Substring</big>** : returns a substring of the specific length starting at the specific offset position.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Substring)]
|
||||
[[play](https://go.dev/play/p/q3sM6ehnPDp)]
|
||||
- **<big>Wrap</big>** : wrap a string with given string.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Wrap)]
|
||||
[[play](https://go.dev/play/p/KoZOlZDDt9y)]
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<div align=center>
|
||||
<a href="https://uvdream.github.io/lancet-docs/"><img src="./logo.png" width="200" height="200"/><a/>
|
||||
<img src="./logo.png" width="200" height="200"/>
|
||||
|
||||
<br/>
|
||||
|
||||

|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://pkg.go.dev/github.com/duke-git/lancet/v2)
|
||||
[](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
|
||||
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
||||
@@ -51,7 +51,7 @@ lancet 是以包的结构组织代码的,使用时需要导入相应的包名
|
||||
import "github.com/duke-git/lancet/v2/strutil"
|
||||
```
|
||||
|
||||
## 例子
|
||||
## 示例
|
||||
|
||||
此处以字符串工具函数 Reverse(逆序字符串)为例,需要导入 strutil 包:
|
||||
|
||||
@@ -112,6 +112,7 @@ import "github.com/duke-git/lancet/v2/algorithm"
|
||||
[[play](https://go.dev/play/p/Anozfr8ZLH3)]
|
||||
- **<big>LinearSearch</big>** : 基于传入的相等函数返回切片中目标值的索引。(线性查找)
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#LinearSearch)]
|
||||
[[play](https://go.dev/play/p/IsS7rgn5s3x)]
|
||||
- **<big>LRUCache</big>** : 应用 lru 算法实现内存缓存.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#LRUCache)]
|
||||
[[play](https://go.dev/play/p/-EZjgOURufP)]
|
||||
@@ -126,24 +127,34 @@ import "github.com/duke-git/lancet/v2/concurrency"
|
||||
|
||||
- **<big>NewChannel</big>** : 返回一个 Channel 指针实例。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#NewChannel)]
|
||||
[[play](https://go.dev/play/p/7aB4KyMMp9A)]
|
||||
- **<big>Bridge</big>** : 将多个 channel 链接到一个 channel,直到取消上下文。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/Bridge.md#NewChannel)]
|
||||
[[play](https://go.dev/play/p/qmWSy1NVF-Y)]
|
||||
- **<big>FanIn</big>** : 将多个 channel 合并为一个 channel,直到取消上下文。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#FanIn)]
|
||||
[[play](https://go.dev/play/p/2VYFMexEvTm)]
|
||||
- **<big>Generate</big>** : 根据传入的值,生成 channel。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#Generate)]
|
||||
[[play](https://go.dev/play/p/7aB4KyMMp9A)]
|
||||
- **<big>Or</big>** : 将一个或多个 channel 读取到一个 channel 中,当任何读取 channel 关闭时将结束读取。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#Or)]
|
||||
[[play](https://go.dev/play/p/Wqz9rwioPww)]
|
||||
- **<big>OrDone</big>** : 将一个 channel 读入另一个 channel,直到取消上下文。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#OrDone)]
|
||||
[[play](https://go.dev/play/p/lm_GoS6aDjo)]
|
||||
- **<big>Repeat</big>** : 返回一个 channel,将参数`values`重复放入 channel,直到取消上下文。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#Repeat)]
|
||||
[[play](https://go.dev/play/p/k5N_ALVmYjE)]
|
||||
- **<big>RepeatFn</big>** : 返回一个 channel,重复执行函数 fn,并将结果放入返回的 channel,直到取消上下文。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#RepeatFn)]
|
||||
[[play](https://go.dev/play/p/4J1zAWttP85)]
|
||||
- **<big>Take</big>** : 返回一个 channel,其值从另一个 channel 获取,直到取消上下文。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#Take)]
|
||||
[[play](https://go.dev/play/p/9Utt-1pDr2J)]
|
||||
- **<big>Tee</big>** : 将一个 channel 分成两个 channel,直到取消上下文。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/concurrency_zh-CN.md#Tee)]
|
||||
[[play](https://go.dev/play/p/3TQPKnCirrP)]
|
||||
|
||||
### 3. condition 包含一些用于条件判断的函数。
|
||||
|
||||
@@ -559,8 +570,10 @@ import "github.com/duke-git/lancet/v2/function"
|
||||
[[play](https://go.dev/play/p/0HqUDIFZ3IL)]
|
||||
- **<big>CurryFn</big>** : 创建柯里化函数。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#CurryFn)]
|
||||
[[play](https://go.dev/play/p/5HopfDwANKX)]
|
||||
- **<big>Compose</big>** : 从右至左组合函数列表fnList,返回组合后的函数。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Compose)]
|
||||
[[play](https://go.dev/play/p/KKfugD4PKYF)]
|
||||
- **<big>Delay</big>** : 延迟delay时间后调用函数。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Delay)]
|
||||
[[play](https://go.dev/play/p/Ivtc2ZE-Tye)]
|
||||
@@ -575,6 +588,7 @@ import "github.com/duke-git/lancet/v2/function"
|
||||
[[play](https://go.dev/play/p/mPdUVvj6HD6)]
|
||||
- **<big>Watcher</big>** : Watcher用于记录代码执行时间。可以启动/停止/重置手表定时器。获取函数执行的时间。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Watcher)]
|
||||
[[play](https://go.dev/play/p/l2yrOpCLd1I)]
|
||||
|
||||
|
||||
### 11. maputil 包括一些操作 map 的函数.
|
||||
@@ -644,6 +658,7 @@ import "github.com/duke-git/lancet/v2/mathutil"
|
||||
[[play](https://go.dev/play/p/N9qgYg_Ho6f)]
|
||||
- **<big>Percent</big>** : 计算百分比,可以指定保留 n 位小数。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Percent)]
|
||||
[[play](https://go.dev/play/p/QQM9B13coSP)]
|
||||
- **<big>RoundToFloat</big>** : 四舍五入,保留 n 位小数,返回 float64。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#RoundToFloat)]
|
||||
[[play](https://go.dev/play/p/ghyb528JRJL)]
|
||||
@@ -1010,6 +1025,7 @@ import "github.com/duke-git/lancet/v2/strutil"
|
||||
[[play](https://go.dev/play/p/Us-ySSbWh-3)]
|
||||
- **<big>Substring</big>** : 根据指定的位置和长度截取子字符串。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Substring)]
|
||||
[[play](https://go.dev/play/p/q3sM6ehnPDp)]
|
||||
- **<big>Wrap</big>** : 用给定字符包裹传入的字符串
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Wrap)]
|
||||
[[play](https://go.dev/play/p/KoZOlZDDt9y)]
|
||||
@@ -1160,7 +1176,6 @@ import "github.com/duke-git/lancet/v2/xerror"
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#Unwrap)]
|
||||
[[play](https://go.dev/play/p/w84d7Mb3Afk)]
|
||||
|
||||
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#Unwrap)
|
||||
|
||||
## 如何贡献代码
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import "github.com/duke-git/lancet/v2/lancetconstraints"
|
||||
|
||||
// LinearSearch return the index of target in slice base on equal function.
|
||||
// If not found return -1
|
||||
// Play: Todo
|
||||
// Play: https://go.dev/play/p/IsS7rgn5s3x
|
||||
func LinearSearch[T any](slice []T, target T, equal func(a, b T) bool) int {
|
||||
for i, v := range slice {
|
||||
if equal(v, target) {
|
||||
|
||||
@@ -20,7 +20,7 @@ func NewChannel[T any]() *Channel[T] {
|
||||
}
|
||||
|
||||
// Generate creates channel, then put values into the channel.
|
||||
// Play: Todo
|
||||
// Play: https://go.dev/play/p/7aB4KyMMp9A
|
||||
func (c *Channel[T]) Generate(ctx context.Context, values ...T) <-chan T {
|
||||
dataStream := make(chan T)
|
||||
|
||||
@@ -40,7 +40,7 @@ func (c *Channel[T]) Generate(ctx context.Context, values ...T) <-chan T {
|
||||
}
|
||||
|
||||
// Repeat create channel, put values into the channel repeatly until cancel the context.
|
||||
// Play: Todo
|
||||
// Play: https://go.dev/play/p/k5N_ALVmYjE
|
||||
func (c *Channel[T]) Repeat(ctx context.Context, values ...T) <-chan T {
|
||||
dataStream := make(chan T)
|
||||
|
||||
@@ -61,7 +61,7 @@ func (c *Channel[T]) Repeat(ctx context.Context, values ...T) <-chan T {
|
||||
|
||||
// RepeatFn create a channel, excutes fn repeatly, and put the result into the channel
|
||||
// until close context.
|
||||
// Play: Todo
|
||||
// Play: https://go.dev/play/p/4J1zAWttP85
|
||||
func (c *Channel[T]) RepeatFn(ctx context.Context, fn func() T) <-chan T {
|
||||
dataStream := make(chan T)
|
||||
|
||||
@@ -79,7 +79,7 @@ func (c *Channel[T]) RepeatFn(ctx context.Context, fn func() T) <-chan T {
|
||||
}
|
||||
|
||||
// Take create a channel whose values are taken from another channel with limit number.
|
||||
// Play: Todo
|
||||
// Play: https://go.dev/play/p/9Utt-1pDr2J
|
||||
func (c *Channel[T]) Take(ctx context.Context, valueStream <-chan T, number int) <-chan T {
|
||||
takeStream := make(chan T)
|
||||
|
||||
@@ -99,7 +99,7 @@ func (c *Channel[T]) Take(ctx context.Context, valueStream <-chan T, number int)
|
||||
}
|
||||
|
||||
// FanIn merge multiple channels into one channel.
|
||||
// Play: Todo
|
||||
// Play: https://go.dev/play/p/2VYFMexEvTm
|
||||
func (c *Channel[T]) FanIn(ctx context.Context, channels ...<-chan T) <-chan T {
|
||||
out := make(chan T)
|
||||
|
||||
@@ -127,7 +127,7 @@ func (c *Channel[T]) FanIn(ctx context.Context, channels ...<-chan T) <-chan T {
|
||||
}
|
||||
|
||||
// Tee split one chanel into two channels, until cancel the context.
|
||||
// Play: Todo
|
||||
// Play: https://go.dev/play/p/3TQPKnCirrP
|
||||
func (c *Channel[T]) Tee(ctx context.Context, in <-chan T) (<-chan T, <-chan T) {
|
||||
out1 := make(chan T)
|
||||
out2 := make(chan T)
|
||||
@@ -154,7 +154,7 @@ func (c *Channel[T]) Tee(ctx context.Context, in <-chan T) (<-chan T, <-chan T)
|
||||
}
|
||||
|
||||
// Bridge link multiply channels into one channel.
|
||||
// Play: Todo
|
||||
// Play: https://go.dev/play/p/qmWSy1NVF-Y
|
||||
func (c *Channel[T]) Bridge(ctx context.Context, chanStream <-chan <-chan T) <-chan T {
|
||||
valStream := make(chan T)
|
||||
|
||||
@@ -186,7 +186,7 @@ func (c *Channel[T]) Bridge(ctx context.Context, chanStream <-chan <-chan T) <-c
|
||||
}
|
||||
|
||||
// Or read one or more channels into one channel, will close when any readin channel is closed.
|
||||
// Play: Todo
|
||||
// Play: https://go.dev/play/p/Wqz9rwioPww
|
||||
func (c *Channel[T]) Or(channels ...<-chan T) <-chan T {
|
||||
switch len(channels) {
|
||||
case 0:
|
||||
@@ -220,7 +220,7 @@ func (c *Channel[T]) Or(channels ...<-chan T) <-chan T {
|
||||
}
|
||||
|
||||
// OrDone read a channel into another channel, will close until cancel context.
|
||||
// Play: Todo
|
||||
// Play: https://go.dev/play/p/lm_GoS6aDjo
|
||||
func (c *Channel[T]) OrDone(ctx context.Context, channel <-chan T) <-chan T {
|
||||
valStream := make(chan T)
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ package datastructure
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/duke-git/lancet/v2/iterator"
|
||||
)
|
||||
|
||||
// List is a linear table, implemented with slice.
|
||||
@@ -316,6 +318,43 @@ func (l *List[T]) Intersection(other *List[T]) *List[T] {
|
||||
return result
|
||||
}
|
||||
|
||||
// Difference returns the difference between two collections.
|
||||
// return a list whose element in the original list, not in the given list.
|
||||
func (l *List[T]) Difference(other *List[T]) *List[T] {
|
||||
result := NewList(make([]T, 0))
|
||||
|
||||
intersectList := l.Intersection(other)
|
||||
|
||||
for _, v := range l.data {
|
||||
if !intersectList.Contain(v) {
|
||||
result.data = append(result.data, v)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// SymmetricDifference oppoiste operation of intersection function.
|
||||
func (l *List[T]) SymmetricDifference(other *List[T]) *List[T] {
|
||||
result := NewList(make([]T, 0))
|
||||
|
||||
intersectList := l.Intersection(other)
|
||||
|
||||
for _, v := range l.data {
|
||||
if !intersectList.Contain(v) {
|
||||
result.data = append(result.data, v)
|
||||
}
|
||||
}
|
||||
|
||||
for _, v := range other.data {
|
||||
if !intersectList.Contain(v) {
|
||||
result.data = append(result.data, v)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// SubList returns a sub list of the original list between the specified fromIndex, inclusive, and toIndex, exclusive.
|
||||
func (l *List[T]) SubList(fromIndex, toIndex int) *List[T] {
|
||||
data := l.data[fromIndex:toIndex]
|
||||
@@ -323,3 +362,57 @@ func (l *List[T]) SubList(fromIndex, toIndex int) *List[T] {
|
||||
copy(subList, data)
|
||||
return NewList(subList)
|
||||
}
|
||||
|
||||
// ForEach performs the given action for each element of the list.
|
||||
func (l *List[T]) ForEach(consumer func(T)) {
|
||||
for _, it := range l.data {
|
||||
consumer(it)
|
||||
}
|
||||
}
|
||||
|
||||
// RetainAll retains only the elements in this list that are contained in the given list.
|
||||
func (l *List[T]) RetainAll(list *List[T]) bool {
|
||||
return l.batchRemove(list, true)
|
||||
}
|
||||
|
||||
// DeleteAll removes from this list all of its elements that are contained in the given list.
|
||||
func (l *List[T]) DeleteAll(list *List[T]) bool {
|
||||
return l.batchRemove(list, false)
|
||||
}
|
||||
|
||||
func (l *List[T]) batchRemove(list *List[T], complement bool) bool {
|
||||
var (
|
||||
w = 0
|
||||
data = l.data
|
||||
size = len(data)
|
||||
)
|
||||
|
||||
for i := 0; i < size; i++ {
|
||||
if list.Contain(data[i]) == complement {
|
||||
data[w] = data[i]
|
||||
w++
|
||||
}
|
||||
}
|
||||
|
||||
if w != size {
|
||||
l.data = data[:w]
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Iterator returns an iterator over the elements in this list in proper sequence.
|
||||
func (l *List[T]) Iterator() iterator.Iterator[T] {
|
||||
return iterator.FromSlice(l.data)
|
||||
}
|
||||
|
||||
// ListToMap convert a list to a map based on iteratee function.
|
||||
func ListToMap[T any, K comparable, V any](list *List[T], iteratee func(T) (K, V)) map[K]V {
|
||||
result := make(map[K]V, list.Size())
|
||||
for _, item := range list.data {
|
||||
k, v := iteratee(item)
|
||||
result[k] = v
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -328,6 +328,28 @@ func TestIntersection(t *testing.T) {
|
||||
assert.Equal(true, expected.Equal(list3))
|
||||
}
|
||||
|
||||
func TestDifference(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestDifference")
|
||||
|
||||
list1 := NewList([]int{1, 2, 3})
|
||||
list2 := NewList([]int{1, 2, 4})
|
||||
expected := NewList([]int{3})
|
||||
|
||||
list3 := list1.Difference(list2)
|
||||
assert.Equal(true, expected.Equal(list3))
|
||||
}
|
||||
|
||||
func TestSymmetricDifference(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSymmetricDifference")
|
||||
|
||||
list1 := NewList([]int{1, 2, 3})
|
||||
list2 := NewList([]int{1, 2, 4})
|
||||
expected := NewList([]int{3, 4})
|
||||
|
||||
list3 := list1.SymmetricDifference(list2)
|
||||
assert.Equal(true, expected.Equal(list3))
|
||||
}
|
||||
|
||||
func TestSubSlice(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSubSlice")
|
||||
|
||||
@@ -357,3 +379,84 @@ func TestDeleteIf(t *testing.T) {
|
||||
assert.Equal([]int{2, 3, 4}, list.Data())
|
||||
assert.Equal(0, count)
|
||||
}
|
||||
|
||||
func TestForEach(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestForEach")
|
||||
|
||||
list := NewList([]int{1, 2, 3, 4})
|
||||
|
||||
rs := make([]int, 0)
|
||||
list.ForEach(func(i int) {
|
||||
rs = append(rs, i)
|
||||
})
|
||||
|
||||
assert.Equal([]int{1, 2, 3, 4}, rs)
|
||||
}
|
||||
|
||||
func TestRetainAll(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestRetainAll")
|
||||
|
||||
list := NewList([]int{1, 2, 3, 4})
|
||||
list1 := NewList([]int{1, 2, 3, 4})
|
||||
list2 := NewList([]int{1, 2, 3, 4})
|
||||
|
||||
retain := NewList([]int{1, 2})
|
||||
retain1 := NewList([]int{2, 3})
|
||||
retain2 := NewList([]int{1, 2, 5})
|
||||
|
||||
list.RetainAll(retain)
|
||||
list1.RetainAll(retain1)
|
||||
list2.RetainAll(retain2)
|
||||
|
||||
assert.Equal([]int{1, 2}, list.Data())
|
||||
assert.Equal([]int{2, 3}, list1.Data())
|
||||
assert.Equal([]int{1, 2}, list2.Data())
|
||||
}
|
||||
|
||||
func TestDeleteAll(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestDeleteAll")
|
||||
|
||||
list := NewList([]int{1, 2, 3, 4})
|
||||
list1 := NewList([]int{1, 2, 3, 4})
|
||||
list2 := NewList([]int{1, 2, 3, 4})
|
||||
|
||||
del := NewList([]int{1})
|
||||
del1 := NewList([]int{2, 3})
|
||||
del2 := NewList([]int{1, 2, 5})
|
||||
|
||||
list.DeleteAll(del)
|
||||
list1.DeleteAll(del1)
|
||||
list2.DeleteAll(del2)
|
||||
assert.Equal([]int{2, 3, 4}, list.Data())
|
||||
assert.Equal([]int{1, 4}, list1.Data())
|
||||
assert.Equal([]int{3, 4}, list2.Data())
|
||||
}
|
||||
|
||||
func TestIterator(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestIterator")
|
||||
|
||||
list := NewList([]int{1, 2, 3, 4})
|
||||
|
||||
iterator := list.Iterator()
|
||||
|
||||
rs := make([]int, 0)
|
||||
for iterator.HasNext() {
|
||||
item, _ := iterator.Next()
|
||||
rs = append(rs, item)
|
||||
}
|
||||
|
||||
assert.Equal([]int{1, 2, 3, 4}, rs)
|
||||
}
|
||||
|
||||
func TestListToMap(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "ListToMap")
|
||||
|
||||
list := NewList([]int{1, 2, 3, 4})
|
||||
|
||||
result := ListToMap(list, func(n int) (int, bool) {
|
||||
return n, n > 1
|
||||
})
|
||||
expected := map[int]bool{1: false, 2: true, 3: true, 4: true}
|
||||
|
||||
assert.Equal(expected, result)
|
||||
}
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
# Algorithm
|
||||
|
||||
Package algorithm implements some basic algorithm. eg. sort, search.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/sort.go](https://github.com/duke-git/lancet/blob/main/algorithm/sort.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/search.go](https://github.com/duke-git/lancet/blob/main/algorithm/search.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go](https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/sort.go](https://github.com/duke-git/lancet/blob/main/algorithm/sort.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/search.go](https://github.com/duke-git/lancet/blob/main/algorithm/search.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go](https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
@@ -22,27 +24,25 @@ import (
|
||||
|
||||
## Index
|
||||
|
||||
- [BubbleSort](#BubbleSort)
|
||||
- [InsertionSort](#InsertionSort)
|
||||
- [SelectionSort](#SelectionSort)
|
||||
- [ShellSort](#ShellSort)
|
||||
- [QuickSort](#QuickSort)
|
||||
- [HeapSort](#HeapSort)
|
||||
- [MergeSort](#MergeSort)
|
||||
- [CountSort](#CountSort)
|
||||
- [BinarySearch](#BinarySearch)
|
||||
- [BinaryIterativeSearch](#BinaryIterativeSearch)
|
||||
- [LinearSearch](#LinearSearch)
|
||||
- [LRUCache](#LRUCache)
|
||||
|
||||
- [BubbleSort](#BubbleSort)
|
||||
- [InsertionSort](#InsertionSort)
|
||||
- [SelectionSort](#SelectionSort)
|
||||
- [ShellSort](#ShellSort)
|
||||
- [QuickSort](#QuickSort)
|
||||
- [HeapSort](#HeapSort)
|
||||
- [MergeSort](#MergeSort)
|
||||
- [CountSort](#CountSort)
|
||||
- [BinarySearch](#BinarySearch)
|
||||
- [BinaryIterativeSearch](#BinaryIterativeSearch)
|
||||
- [LinearSearch](#LinearSearch)
|
||||
- [LRUCache](#LRUCache)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
|
||||
### <span id="BubbleSort">BubbleSort</span>
|
||||
|
||||
<p>Sort slice with bubble sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -50,6 +50,7 @@ import (
|
||||
```go
|
||||
func BubbleSort[T any](slice []T, comparator lancetconstraints.Comparator)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -60,34 +61,36 @@ import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
func main() {
|
||||
numbers := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
algorithm.BubbleSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
algorithm.BubbleSort(numbers, comparator)
|
||||
|
||||
fmt.Println(numbers)
|
||||
|
||||
// Output:
|
||||
// [1 2 3 4 5 6]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="InsertionSort">InsertionSort</span>
|
||||
|
||||
<p>Sort slice with insertion sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -95,6 +98,7 @@ func main() {
|
||||
```go
|
||||
func InsertionSort[T any](slice []T, comparator lancetconstraints.Comparator)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -105,54 +109,51 @@ import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
type people struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
// PeopleAageComparator sort people slice by age field
|
||||
type peopleAgeComparator struct{}
|
||||
|
||||
// Compare implements github.com/duke-git/lancet/lancetconstraints/constraints.go/Comparator
|
||||
func (pc *peopleAgeComparator) Compare(v1 any, v2 any) int {
|
||||
p1, _ := v1.(people)
|
||||
p2, _ := v2.(people)
|
||||
|
||||
//ascending order
|
||||
if p1.Age < p2.Age {
|
||||
return -1
|
||||
} else if p1.Age > p2.Age {
|
||||
return 1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func main() {
|
||||
type people struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
// PeopleAageComparator sort people slice by age field
|
||||
type peopleAgeComparator struct{}
|
||||
|
||||
// Compare implements github.com/duke-git/lancet/lancetconstraints/constraints.go/Comparator
|
||||
func (pc *peopleAgeComparator) Compare(v1 any, v2 any) int {
|
||||
p1, _ := v1.(people)
|
||||
p2, _ := v2.(people)
|
||||
|
||||
//ascending order
|
||||
if p1.Age < p2.Age {
|
||||
return -1
|
||||
} else if p1.Age > p2.Age {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
|
||||
//decending order
|
||||
// if p1.Age > p2.Age {
|
||||
// return -1
|
||||
// } else if p1.Age < p2.Age {
|
||||
// return 1
|
||||
// }
|
||||
}
|
||||
|
||||
var peoples = []people{
|
||||
peoples := []people{
|
||||
{Name: "a", Age: 20},
|
||||
{Name: "b", Age: 10},
|
||||
{Name: "c", Age: 17},
|
||||
{Name: "d", Age: 8},
|
||||
{Name: "e", Age: 28},
|
||||
}
|
||||
|
||||
comparator := &peopleAgeComparator{}
|
||||
|
||||
algorithm.InsertionSort(peoples, comparator)
|
||||
|
||||
fmt.Println(peoples) //[{d 8} {b 10} {c 17} {a 20} {e 28}]
|
||||
fmt.Println(peoples)
|
||||
|
||||
// Output:
|
||||
// [{d 8} {b 10} {c 17} {a 20} {e 28}]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="SelectionSort">SelectionSort</span>
|
||||
|
||||
<p>Sort slice with selection sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -160,6 +161,7 @@ func main() {
|
||||
```go
|
||||
func SelectionSort[T any](slice []T, comparator lancetconstraints.Comparator)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -170,34 +172,36 @@ import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
func main() {
|
||||
numbers := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
algorithm.SelectionSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
algorithm.SelectionSort(numbers, comparator)
|
||||
|
||||
fmt.Println(numbers)
|
||||
|
||||
// Output:
|
||||
// [1 2 3 4 5 6]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="ShellSort">ShellSort</span>
|
||||
|
||||
<p>Sort slice with shell sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -205,6 +209,7 @@ func main() {
|
||||
```go
|
||||
func ShellSort[T any](slice []T, comparator lancetconstraints.Comparator)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -215,34 +220,36 @@ import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
func main() {
|
||||
numbers := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
algorithm.ShellSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
algorithm.ShellSort(numbers, comparator)
|
||||
|
||||
fmt.Println(numbers)
|
||||
|
||||
// Output:
|
||||
// [1 2 3 4 5 6]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="QuickSort">QuickSort</span>
|
||||
|
||||
<p>Sort slice with quick sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -250,6 +257,7 @@ func main() {
|
||||
```go
|
||||
func QuickSort[T any](slice []T comparator lancetconstraints.Comparator)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -260,34 +268,36 @@ import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
func main() {
|
||||
numbers := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
algorithm.QuickSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
algorithm.QuickSort(numbers, comparator)
|
||||
|
||||
fmt.Println(numbers)
|
||||
|
||||
// Output:
|
||||
// [1 2 3 4 5 6]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="HeapSort">HeapSort</span>
|
||||
|
||||
<p>Sort slice with heap sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -295,6 +305,7 @@ func main() {
|
||||
```go
|
||||
func HeapSort[T any](slice []T, comparator lancetconstraints.Comparator)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -305,34 +316,36 @@ import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
func main() {
|
||||
numbers := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
algorithm.HeapSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
algorithm.HeapSort(numbers, comparator)
|
||||
|
||||
fmt.Println(numbers)
|
||||
|
||||
// Output:
|
||||
// [1 2 3 4 5 6]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="MergeSort">MergeSort</span>
|
||||
|
||||
<p>Sort slice with merge sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -340,6 +353,7 @@ func main() {
|
||||
```go
|
||||
func MergeSort[T any](slice []T, comparator lancetconstraints.Comparator)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -350,33 +364,36 @@ import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
func main() {
|
||||
numbers := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
algorithm.MergeSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
algorithm.MergeSort(numbers, comparator)
|
||||
|
||||
fmt.Println(numbers)
|
||||
|
||||
// Output:
|
||||
// [1 2 3 4 5 6]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="CountSort">CountSort</span>
|
||||
|
||||
<p>Sort slice with count sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -384,6 +401,7 @@ func main() {
|
||||
```go
|
||||
func CountSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -394,34 +412,37 @@ import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
type intComparator struct{}
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
func main() {
|
||||
numbers := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
sortedSlice := algorithm.CountSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
sortedNums := algorithm.CountSort(numbers, comparator)
|
||||
|
||||
fmt.Println(sortedNums)
|
||||
|
||||
// Output:
|
||||
// [1 2 3 4 5 6]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="BinarySearch">BinarySearch</span>
|
||||
|
||||
<p>BinarySearch search for target within a sorted slice, recursive call itself. If a target is found, the index of the target is returned. Else the function return -1.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -429,6 +450,7 @@ func main() {
|
||||
```go
|
||||
func BinarySearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -439,35 +461,39 @@ import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var sortedNumbers = []int{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
func main() {
|
||||
numbers := []int{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
comparator := &intComparator{}
|
||||
foundIndex := algorithm.BinarySearch(sortedNumbers, 5, 0, len(sortedNumbers)-1, comparator)
|
||||
fmt.Println(foundIndex) //4
|
||||
|
||||
notFoundIndex := algorithm.BinarySearch(sortedNumbers, 9, 0, len(sortedNumbers)-1, comparator)
|
||||
fmt.Println(notFoundIndex) //-1
|
||||
result1 := algorithm.BinarySearch(numbers, 5, 0, len(numbers)-1, comparator)
|
||||
result2 := algorithm.BinarySearch(numbers, 9, 0, len(numbers)-1, comparator)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// 4
|
||||
// -1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="BinaryIterativeSearch">BinaryIterativeSearch</span>
|
||||
|
||||
<p>BinaryIterativeSearch search for target within a sorted slice, recursive call itself. If a target is found, the index of the target is returned. Else the function return -1.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -475,6 +501,7 @@ func main() {
|
||||
```go
|
||||
func BinaryIterativeSearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -485,43 +512,47 @@ import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var sortedNumbers = []int{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
func main() {
|
||||
numbers := []int{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
comparator := &intComparator{}
|
||||
foundIndex := algorithm.BinaryIterativeSearch(sortedNumbers, 5, 0, len(sortedNumbers)-1, comparator)
|
||||
fmt.Println(foundIndex) //4
|
||||
|
||||
notFoundIndex := algorithm.BinaryIterativeSearch(sortedNumbers, 9, 0, len(sortedNumbers)-1, comparator)
|
||||
fmt.Println(notFoundIndex) //-1
|
||||
result1 := algorithm.BinaryIterativeSearch(numbers, 5, 0, len(numbers)-1, comparator)
|
||||
result2 := algorithm.BinaryIterativeSearch(numbers, 9, 0, len(numbers)-1, comparator)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// 4
|
||||
// -1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="LinearSearch">LinearSearch</span>
|
||||
<p>LinearSearch Simple linear search algorithm that iterates over all elements of an slice. If a target is found, the index of the target is returned. Else the function return -1.</p>
|
||||
|
||||
<p>return the index of target in slice base on equal function.If a target is found, the index of the target is returned. Else the function return -1.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func LinearSearch[T any](slice []T, target T, comparator lancetconstraints.Comparator) int
|
||||
func LinearSearch[T any](slice []T, target T, equal func(a, b T) bool) int
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -533,35 +564,26 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
numbers := []int{3, 4, 5, 3, 2, 1}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
equalFunc := func(a, b int) bool {
|
||||
return a == b
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
foundIndex := algorithm.LinearSearch(intSlice, 5, comparator)
|
||||
fmt.Println(foundIndex) //2
|
||||
result1 := algorithm.LinearSearch(numbers, 3, equalFunc)
|
||||
result2 := algorithm.LinearSearch(numbers, 6, equalFunc)
|
||||
|
||||
notFoundIndex := algorithm.LinearSearch(sortedNumbers, 0, comparator)
|
||||
fmt.Println(notFoundIndex) //-1
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// 0
|
||||
// -1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="LRUCache">LRUCache</span>
|
||||
|
||||
<p>LRUCache implements mem cache with lru.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -573,6 +595,7 @@ func (l *LRUCache[K, V]) Put(key K, value V)
|
||||
func (l *LRUCache[K, V]) Delete(key K) bool
|
||||
func (l *LRUCache[K, V]) Len() int
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -588,14 +611,26 @@ func main() {
|
||||
|
||||
cache.Put(1, 1)
|
||||
cache.Put(2, 2)
|
||||
cache.Put(3, 3)
|
||||
|
||||
fmt.Println(cache.Len()) // 3
|
||||
result1, ok1 := cache.Get(1)
|
||||
result2, ok2 := cache.Get(2)
|
||||
result3, ok3 := cache.Get(3)
|
||||
|
||||
v, ok := cache.Get(1)
|
||||
fmt.Println(v, ok) // 1 true
|
||||
fmt.Println(result1, ok1)
|
||||
fmt.Println(result2, ok2)
|
||||
fmt.Println(result3, ok3)
|
||||
|
||||
ok = cache.Delete(1)
|
||||
fmt.Println(ok) // true
|
||||
fmt.Println(cache.Len())
|
||||
|
||||
ok := cache.Delete(2)
|
||||
fmt.Println(ok)
|
||||
|
||||
|
||||
// Output:
|
||||
// 1 true
|
||||
// 2 true
|
||||
// 0 false
|
||||
// 2
|
||||
// true
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
# Algorithm
|
||||
algorithm算法包实现一些基本算法,sort,search,lrucache。
|
||||
|
||||
algorithm 算法包实现一些基本算法,sort,search,lrucache。
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 源码
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/sort.go](https://github.com/duke-git/lancet/blob/main/algorithm/sort.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/search.go](https://github.com/duke-git/lancet/blob/main/algorithm/search.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go](https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/sort.go](https://github.com/duke-git/lancet/blob/main/algorithm/sort.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/search.go](https://github.com/duke-git/lancet/blob/main/algorithm/search.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go](https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
@@ -22,35 +24,34 @@ import (
|
||||
|
||||
## 目录
|
||||
|
||||
- [BubbleSort](#BubbleSort)
|
||||
- [InsertionSort](#InsertionSort)
|
||||
- [SelectionSort](#SelectionSort)
|
||||
- [ShellSort](#ShellSort)
|
||||
- [QuickSort](#QuickSort)
|
||||
- [HeapSort](#HeapSort)
|
||||
- [MergeSort](#MergeSort)
|
||||
- [CountSort](#CountSort)
|
||||
- [BinarySearch](#BinarySearch)
|
||||
- [BinaryIterativeSearch](#BinaryIterativeSearch)
|
||||
- [LinearSearch](#LinearSearch)
|
||||
- [LRUCache](#LRUCache)
|
||||
|
||||
- [BubbleSort](#BubbleSort)
|
||||
- [InsertionSort](#InsertionSort)
|
||||
- [SelectionSort](#SelectionSort)
|
||||
- [ShellSort](#ShellSort)
|
||||
- [QuickSort](#QuickSort)
|
||||
- [HeapSort](#HeapSort)
|
||||
- [MergeSort](#MergeSort)
|
||||
- [CountSort](#CountSort)
|
||||
- [BinarySearch](#BinarySearch)
|
||||
- [BinaryIterativeSearch](#BinaryIterativeSearch)
|
||||
- [LinearSearch](#LinearSearch)
|
||||
- [LRUCache](#LRUCache)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 文档
|
||||
|
||||
|
||||
|
||||
### <span id="BubbleSort">BubbleSort</span>
|
||||
<p>冒泡排序,参数comparator需要实现包lancetconstraints.Comparator</p>
|
||||
|
||||
<p>冒泡排序,参数comparator需要实现包lancetconstraints.Comparator。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func BubbleSort[T any](slice []T, comparator lancetconstraints.Comparator)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -60,42 +61,45 @@ import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
func main() {
|
||||
numbers := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
algorithm.BubbleSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
algorithm.BubbleSort(numbers, comparator)
|
||||
|
||||
fmt.Println(numbers)
|
||||
|
||||
// Output:
|
||||
// [1 2 3 4 5 6]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="InsertionSort">InsertionSort</span>
|
||||
<p>插入排序,参数comparator需要实现包lancetconstraints.Comparator</p>
|
||||
|
||||
<p>插入排序,参数comparator需要实现包lancetconstraints.Comparator。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func InsertionSort[T any](slice []T, comparator lancetconstraints.Comparator)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -105,62 +109,60 @@ import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
type people struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
// PeopleAageComparator sort people slice by age field
|
||||
type peopleAgeComparator struct{}
|
||||
|
||||
// Compare implements github.com/duke-git/lancet/lancetconstraints/constraints.go/Comparator
|
||||
func (pc *peopleAgeComparator) Compare(v1 any, v2 any) int {
|
||||
p1, _ := v1.(people)
|
||||
p2, _ := v2.(people)
|
||||
|
||||
//ascending order
|
||||
if p1.Age < p2.Age {
|
||||
return -1
|
||||
} else if p1.Age > p2.Age {
|
||||
return 1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func main() {
|
||||
type people struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
// PeopleAageComparator sort people slice by age field
|
||||
type peopleAgeComparator struct{}
|
||||
|
||||
// Compare implements github.com/duke-git/lancet/lancetconstraints/constraints.go/Comparator
|
||||
func (pc *peopleAgeComparator) Compare(v1 any, v2 any) int {
|
||||
p1, _ := v1.(people)
|
||||
p2, _ := v2.(people)
|
||||
|
||||
//ascending order
|
||||
if p1.Age < p2.Age {
|
||||
return -1
|
||||
} else if p1.Age > p2.Age {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
|
||||
//decending order
|
||||
// if p1.Age > p2.Age {
|
||||
// return -1
|
||||
// } else if p1.Age < p2.Age {
|
||||
// return 1
|
||||
// }
|
||||
}
|
||||
|
||||
var peoples = []people{
|
||||
peoples := []people{
|
||||
{Name: "a", Age: 20},
|
||||
{Name: "b", Age: 10},
|
||||
{Name: "c", Age: 17},
|
||||
{Name: "d", Age: 8},
|
||||
{Name: "e", Age: 28},
|
||||
}
|
||||
|
||||
comparator := &peopleAgeComparator{}
|
||||
|
||||
algorithm.InsertionSort(peoples, comparator)
|
||||
|
||||
fmt.Println(intSlice) //[{d 8} {b 10} {c 17} {a 20} {e 28}]
|
||||
fmt.Println(peoples)
|
||||
|
||||
// Output:
|
||||
// [{d 8} {b 10} {c 17} {a 20} {e 28}]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="SelectionSort">SelectionSort</span>
|
||||
<p>选择排序,参数comparator需要实现包lancetconstraints.Comparator</p>
|
||||
|
||||
<p>选择排序,参数comparator需要实现包lancetconstraints.Comparator。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func SelectionSort[T any](slice []T, comparator lancetconstraints.Comparator)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -170,42 +172,45 @@ import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
func main() {
|
||||
numbers := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
algorithm.SelectionSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
algorithm.SelectionSort(numbers, comparator)
|
||||
|
||||
fmt.Println(numbers)
|
||||
|
||||
// Output:
|
||||
// [1 2 3 4 5 6]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="ShellSort">ShellSort</span>
|
||||
<p>希尔排序,参数comparator需要实现包lancetconstraints.Comparator</p>
|
||||
|
||||
<p>希尔排序,参数comparator需要实现包lancetconstraints.Comparator。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ShellSort[T any](slice []T, comparator lancetconstraints.Comparator)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -215,42 +220,45 @@ import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
func main() {
|
||||
numbers := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
algorithm.ShellSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
algorithm.ShellSort(numbers, comparator)
|
||||
|
||||
fmt.Println(numbers)
|
||||
|
||||
// Output:
|
||||
// [1 2 3 4 5 6]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="QuickSort">QuickSort</span>
|
||||
<p>快速排序,参数comparator需要实现包lancetconstraints.Comparator</p>
|
||||
|
||||
<p>快速排序,参数comparator需要实现包lancetconstraints.Comparator。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func QuickSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
|
||||
func QuickSort[T any](slice []T comparator lancetconstraints.Comparator)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -260,42 +268,45 @@ import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
func main() {
|
||||
numbers := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
algorithm.QuickSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
algorithm.QuickSort(numbers, comparator)
|
||||
|
||||
fmt.Println(numbers)
|
||||
|
||||
// Output:
|
||||
// [1 2 3 4 5 6]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="HeapSort">HeapSort</span>
|
||||
<p>堆排序,参数comparator需要实现包lancetconstraints.Comparator</p>
|
||||
|
||||
<p>堆排序,参数comparator需要实现包lancetconstraints.Comparator。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func HeapSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
|
||||
func HeapSort[T any](slice []T, comparator lancetconstraints.Comparator)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -305,42 +316,45 @@ import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
func main() {
|
||||
numbers := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
algorithm.HeapSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
algorithm.HeapSort(numbers, comparator)
|
||||
|
||||
fmt.Println(numbers)
|
||||
|
||||
// Output:
|
||||
// [1 2 3 4 5 6]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="MergeSort">MergeSort</span>
|
||||
<p>归并排序,参数comparator需要实现包lancetconstraints.Comparator</p>
|
||||
|
||||
<p>归并排序,参数comparator需要实现包lancetconstraints.Comparator。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func MergeSort[T any](slice []T, comparator lancetconstraints.Comparator)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -350,41 +364,45 @@ import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
func main() {
|
||||
numbers := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
algorithm.MergeSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(intSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
algorithm.MergeSort(numbers, comparator)
|
||||
|
||||
fmt.Println(numbers)
|
||||
|
||||
// Output:
|
||||
// [1 2 3 4 5 6]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="CountSort">CountSort</span>
|
||||
<p>计数排序,参数comparator需要实现包lancetconstraints.Comparator</p>
|
||||
|
||||
<p>计数排序,参数comparator需要实现包lancetconstraints.Comparator。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func CountSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -394,42 +412,46 @@ import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
type intComparator struct{}
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
func main() {
|
||||
numbers := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
sortedSlice := algorithm.CountSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
sortedNums := algorithm.CountSort(numbers, comparator)
|
||||
|
||||
fmt.Println(sortedNums)
|
||||
|
||||
// Output:
|
||||
// [1 2 3 4 5 6]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="BinarySearch">BinarySearch</span>
|
||||
<p>二分递归查找,返回元素索引,未找到元素返回-1,参数comparator需要实现包lancetconstraints.Comparator</p>
|
||||
|
||||
<p>二分递归查找,返回元素索引,未找到元素返回-1,参数comparator需要实现包lancetconstraints.Comparator。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func BinarySearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -439,43 +461,48 @@ import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var sortedNumbers = []int{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
func main() {
|
||||
numbers := []int{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
comparator := &intComparator{}
|
||||
foundIndex := algorithm.BinarySearch(sortedNumbers, 5, 0, len(sortedNumbers)-1, comparator)
|
||||
fmt.Println(foundIndex) //4
|
||||
|
||||
notFoundIndex := algorithm.BinarySearch(sortedNumbers, 9, 0, len(sortedNumbers)-1, comparator)
|
||||
fmt.Println(notFoundIndex) //-1
|
||||
result1 := algorithm.BinarySearch(numbers, 5, 0, len(numbers)-1, comparator)
|
||||
result2 := algorithm.BinarySearch(numbers, 9, 0, len(numbers)-1, comparator)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// 4
|
||||
// -1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="BinaryIterativeSearch">BinaryIterativeSearch</span>
|
||||
<p>二分迭代查找,返回元素索引,未找到元素返回-1,参数comparator需要实现包lancetconstraints.Comparator</p>
|
||||
|
||||
<p>二分迭代查找,返回元素索引,未找到元素返回-1,参数comparator需要实现包lancetconstraints.Comparator。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func BinaryIterativeSearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -485,44 +512,48 @@ import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var sortedNumbers = []int{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
func main() {
|
||||
numbers := []int{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
comparator := &intComparator{}
|
||||
foundIndex := algorithm.BinaryIterativeSearch(sortedNumbers, 5, 0, len(sortedNumbers)-1, comparator)
|
||||
fmt.Println(foundIndex) //4
|
||||
|
||||
notFoundIndex := algorithm.BinaryIterativeSearch(sortedNumbers, 9, 0, len(sortedNumbers)-1, comparator)
|
||||
fmt.Println(notFoundIndex) //-1
|
||||
result1 := algorithm.BinaryIterativeSearch(numbers, 5, 0, len(numbers)-1, comparator)
|
||||
result2 := algorithm.BinaryIterativeSearch(numbers, 9, 0, len(numbers)-1, comparator)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// 4
|
||||
// -1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="LinearSearch">LinearSearch</span>
|
||||
<p>线性查找,返回元素索引,未找到元素返回-1,参数comparator需要实现包lancetconstraints.Comparator</p>
|
||||
|
||||
<p>基于传入的相等函数线性查找元素,返回元素索引,未找到元素返回-1。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func LinearSearch[T any](slice []T, target T, comparator lancetconstraints.Comparator) int
|
||||
func LinearSearch[T any](slice []T, target T, equal func(a, b T) bool) int
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -533,36 +564,27 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
numbers := []int{3, 4, 5, 3, 2, 1}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
equalFunc := func(a, b int) bool {
|
||||
return a == b
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
foundIndex := algorithm.LinearSearch(intSlice, 5, comparator)
|
||||
fmt.Println(foundIndex) //2
|
||||
result1 := algorithm.LinearSearch(numbers, 3, equalFunc)
|
||||
result2 := algorithm.LinearSearch(numbers, 6, equalFunc)
|
||||
|
||||
notFoundIndex := algorithm.LinearSearch(sortedNumbers, 0, comparator)
|
||||
fmt.Println(notFoundIndex) //-1
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// 0
|
||||
// -1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="LRUCache">LRUCache</span>
|
||||
<p>lru实现缓存</p>
|
||||
|
||||
<p>lru算法实现缓存。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
@@ -573,7 +595,8 @@ func (l *LRUCache[K, V]) Put(key K, value V)
|
||||
func (l *LRUCache[K, V]) Delete(key K) bool
|
||||
func (l *LRUCache[K, V]) Len() int
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -588,14 +611,26 @@ func main() {
|
||||
|
||||
cache.Put(1, 1)
|
||||
cache.Put(2, 2)
|
||||
cache.Put(3, 3)
|
||||
|
||||
fmt.Println(cache.Len()) // 3
|
||||
result1, ok1 := cache.Get(1)
|
||||
result2, ok2 := cache.Get(2)
|
||||
result3, ok3 := cache.Get(3)
|
||||
|
||||
v, ok := cache.Get(1)
|
||||
fmt.Println(v, ok) // 1 true
|
||||
fmt.Println(result1, ok1)
|
||||
fmt.Println(result2, ok2)
|
||||
fmt.Println(result3, ok3)
|
||||
|
||||
ok = cache.Delete(1)
|
||||
fmt.Println(ok) // true
|
||||
fmt.Println(cache.Len())
|
||||
|
||||
ok := cache.Delete(2)
|
||||
fmt.Println(ok)
|
||||
|
||||
|
||||
// Output:
|
||||
// 1 true
|
||||
// 2 true
|
||||
// 0 false
|
||||
// 2
|
||||
// true
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
@@ -61,8 +61,6 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Bridge">Bridge</span>
|
||||
|
||||
<p>Link multiple channels into one channel until cancel the context.</p>
|
||||
@@ -84,39 +82,37 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
c := concurrency.NewChannel[int]()
|
||||
genVals := func() <-chan <-chan int {
|
||||
out := make(chan (<-chan int))
|
||||
go func() {
|
||||
defer close(out)
|
||||
for i := 1; i <= 5; i++ {
|
||||
stream := make(chan int, 1)
|
||||
stream <- i
|
||||
close(stream)
|
||||
out <- stream
|
||||
}
|
||||
}()
|
||||
return out
|
||||
}
|
||||
c := concurrency.NewChannel[int]()
|
||||
genVals := func() <-chan <-chan int {
|
||||
out := make(chan (<-chan int))
|
||||
go func() {
|
||||
defer close(out)
|
||||
for i := 1; i <= 5; i++ {
|
||||
stream := make(chan int, 1)
|
||||
stream <- i
|
||||
close(stream)
|
||||
out <- stream
|
||||
}
|
||||
}()
|
||||
return out
|
||||
}
|
||||
|
||||
for v := range c.Bridge(ctx, genVals()) {
|
||||
fmt.Println(v)
|
||||
}
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
// 3
|
||||
// 4
|
||||
// 5
|
||||
for v := range c.Bridge(ctx, genVals()) {
|
||||
fmt.Println(v)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
// 3
|
||||
// 4
|
||||
// 5
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="FanIn">FanIn</span>
|
||||
|
||||
<p>Merge multiple channels into one channel until cancel the context.</p>
|
||||
@@ -138,25 +134,24 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
c := concurrency.NewChannel[int]()
|
||||
channels := make([]<-chan int, 2)
|
||||
c := concurrency.NewChannel[int]()
|
||||
channels := make([]<-chan int, 2)
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
channels[i] = c.Take(ctx, c.Repeat(ctx, i), 2)
|
||||
}
|
||||
for i := 0; i < 2; i++ {
|
||||
channels[i] = c.Take(ctx, c.Repeat(ctx, i), 2)
|
||||
}
|
||||
|
||||
chs := c.FanIn(ctx, channels...)
|
||||
chs := c.FanIn(ctx, channels...)
|
||||
|
||||
for v := range chs {
|
||||
fmt.Println(v) //1 1 0 0 or 0 0 1 1
|
||||
}
|
||||
for v := range chs {
|
||||
fmt.Println(v) //1 1 0 0 or 0 0 1 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="Repeat">Repeat</span>
|
||||
|
||||
<p>Create channel, put values into the channel repeatly until cancel the context.</p>
|
||||
@@ -178,25 +173,24 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
c := concurrency.NewChannel[int]()
|
||||
intStream := c.Take(ctx, c.Repeat(ctx, 1, 2), 4)
|
||||
c := concurrency.NewChannel[int]()
|
||||
intStream := c.Take(ctx, c.Repeat(ctx, 1, 2), 4)
|
||||
|
||||
for v := range intStream {
|
||||
fmt.Println(v)
|
||||
}
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
// 1
|
||||
// 2
|
||||
for v := range intStream {
|
||||
fmt.Println(v)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
// 1
|
||||
// 2
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Generate">Generate</span>
|
||||
|
||||
<p>Creates a channel, then put values into the channel.</p>
|
||||
@@ -218,20 +212,20 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
c := concurrency.NewChannel[int]()
|
||||
intStream := c.Generate(ctx, 1, 2, 3)
|
||||
c := concurrency.NewChannel[int]()
|
||||
intStream := c.Generate(ctx, 1, 2, 3)
|
||||
|
||||
fmt.Println(<-intStream)
|
||||
fmt.Println(<-intStream)
|
||||
fmt.Println(<-intStream)
|
||||
fmt.Println(<-intStream)
|
||||
fmt.Println(<-intStream)
|
||||
fmt.Println(<-intStream)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
// 3
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
// 3
|
||||
}
|
||||
```
|
||||
|
||||
@@ -256,28 +250,27 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
fn := func() string {
|
||||
return "hello"
|
||||
}
|
||||
fn := func() string {
|
||||
return "hello"
|
||||
}
|
||||
|
||||
c := concurrency.NewChannel[string]()
|
||||
intStream := c.Take(ctx, c.RepeatFn(ctx, fn), 3)
|
||||
c := concurrency.NewChannel[string]()
|
||||
intStream := c.Take(ctx, c.RepeatFn(ctx, fn), 3)
|
||||
|
||||
for v := range intStream {
|
||||
fmt.Println(v)
|
||||
}
|
||||
// Output:
|
||||
// hello
|
||||
// hello
|
||||
// hello
|
||||
for v := range intStream {
|
||||
fmt.Println(v)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
// hello
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Or">Or</span>
|
||||
|
||||
<p>Read one or more channels into one channel, will close when any readin channel is closed.</p>
|
||||
@@ -299,31 +292,28 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
sig := func(after time.Duration) <-chan any {
|
||||
c := make(chan any)
|
||||
go func() {
|
||||
defer close(c)
|
||||
time.Sleep(after)
|
||||
}()
|
||||
return c
|
||||
}
|
||||
sig := func(after time.Duration) <-chan any {
|
||||
c := make(chan any)
|
||||
go func() {
|
||||
defer close(c)
|
||||
time.Sleep(after)
|
||||
}()
|
||||
return c
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
start := time.Now()
|
||||
|
||||
c := concurrency.NewChannel[any]()
|
||||
<-c.Or(
|
||||
sig(1*time.Second),
|
||||
sig(2*time.Second),
|
||||
sig(3*time.Second),
|
||||
)
|
||||
c := concurrency.NewChannel[any]()
|
||||
<-c.Or(
|
||||
sig(1*time.Second),
|
||||
sig(2*time.Second),
|
||||
sig(3*time.Second),
|
||||
)
|
||||
|
||||
fmt.Println("done after %v", time.Since(start)) //1.003s
|
||||
fmt.Println("done after %v", time.Since(start)) //1.003s
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="OrDone">OrDone</span>
|
||||
|
||||
<p>Read a channel into another channel, will close until cancel context.</p>
|
||||
@@ -345,25 +335,23 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
c := concurrency.NewChannel[int]()
|
||||
intStream := c.Take(ctx, c.Repeat(ctx, 1), 3)
|
||||
c := concurrency.NewChannel[int]()
|
||||
intStream := c.Take(ctx, c.Repeat(ctx, 1), 3)
|
||||
|
||||
for v := range c.OrDone(ctx, intStream) {
|
||||
fmt.Println(v)
|
||||
}
|
||||
// Output:
|
||||
// 1
|
||||
// 1
|
||||
// 1
|
||||
for v := range c.OrDone(ctx, intStream) {
|
||||
fmt.Println(v)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 1
|
||||
// 1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="Take">Take</span>
|
||||
|
||||
<p>Create a channel whose values are taken from another channel with limit number.</p>
|
||||
@@ -385,32 +373,31 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
numbers := make(chan int, 5)
|
||||
numbers <- 1
|
||||
numbers <- 2
|
||||
numbers <- 3
|
||||
numbers <- 4
|
||||
numbers <- 5
|
||||
defer close(numbers)
|
||||
numbers := make(chan int, 5)
|
||||
numbers <- 1
|
||||
numbers <- 2
|
||||
numbers <- 3
|
||||
numbers <- 4
|
||||
numbers <- 5
|
||||
defer close(numbers)
|
||||
|
||||
c := concurrency.NewChannel[int]()
|
||||
intStream := c.Take(ctx, numbers, 3)
|
||||
c := concurrency.NewChannel[int]()
|
||||
intStream := c.Take(ctx, numbers, 3)
|
||||
|
||||
for v := range intStream {
|
||||
fmt.Println(v)
|
||||
}
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
// 3
|
||||
for v := range intStream {
|
||||
fmt.Println(v)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
// 3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Tee">Tee</span>
|
||||
|
||||
<p>Split one chanel into two channels, until cancel the context.</p>
|
||||
@@ -432,22 +419,23 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
c := concurrency.NewChannel[int]()
|
||||
intStream := c.Take(ctx, c.Repeat(ctx, 1), 2)
|
||||
c := concurrency.NewChannel[int]()
|
||||
intStream := c.Take(ctx, c.Repeat(ctx, 1), 2)
|
||||
|
||||
ch1, ch2 := c.Tee(ctx, intStream)
|
||||
ch1, ch2 := c.Tee(ctx, intStream)
|
||||
|
||||
for v := range ch1 {
|
||||
fmt.Println(v)
|
||||
fmt.Println(<-ch2)
|
||||
}
|
||||
// Output:
|
||||
// 1
|
||||
// 1
|
||||
// 1
|
||||
// 1
|
||||
for v := range ch1 {
|
||||
fmt.Println(v)
|
||||
fmt.Println(<-ch2)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 1
|
||||
// 1
|
||||
// 1
|
||||
}
|
||||
```
|
||||
@@ -46,7 +46,7 @@ import (
|
||||
type Channel[T any] struct
|
||||
func NewChannel[T any]() *Channel[T]
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -61,8 +61,6 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Bridge">Bridge</span>
|
||||
|
||||
<p>将多个channel链接到一个channel,直到取消上下文。</p>
|
||||
@@ -72,7 +70,7 @@ func main() {
|
||||
```go
|
||||
func (c *Channel[T]) Bridge(ctx context.Context, chanStream <-chan <-chan T) <-chan T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -84,39 +82,37 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
c := concurrency.NewChannel[int]()
|
||||
genVals := func() <-chan <-chan int {
|
||||
out := make(chan (<-chan int))
|
||||
go func() {
|
||||
defer close(out)
|
||||
for i := 1; i <= 5; i++ {
|
||||
stream := make(chan int, 1)
|
||||
stream <- i
|
||||
close(stream)
|
||||
out <- stream
|
||||
}
|
||||
}()
|
||||
return out
|
||||
}
|
||||
c := concurrency.NewChannel[int]()
|
||||
genVals := func() <-chan <-chan int {
|
||||
out := make(chan (<-chan int))
|
||||
go func() {
|
||||
defer close(out)
|
||||
for i := 1; i <= 5; i++ {
|
||||
stream := make(chan int, 1)
|
||||
stream <- i
|
||||
close(stream)
|
||||
out <- stream
|
||||
}
|
||||
}()
|
||||
return out
|
||||
}
|
||||
|
||||
for v := range c.Bridge(ctx, genVals()) {
|
||||
fmt.Println(v)
|
||||
}
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
// 3
|
||||
// 4
|
||||
// 5
|
||||
for v := range c.Bridge(ctx, genVals()) {
|
||||
fmt.Println(v)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
// 3
|
||||
// 4
|
||||
// 5
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="FanIn">FanIn</span>
|
||||
|
||||
<p>将多个channel合并为一个channel,直到取消上下文。</p>
|
||||
@@ -126,7 +122,7 @@ func main() {
|
||||
```go
|
||||
func (c *Channel[T]) FanIn(ctx context.Context, channels ...<-chan T) <-chan T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -138,25 +134,24 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
c := concurrency.NewChannel[int]()
|
||||
channels := make([]<-chan int, 2)
|
||||
c := concurrency.NewChannel[int]()
|
||||
channels := make([]<-chan int, 2)
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
channels[i] = c.Take(ctx, c.Repeat(ctx, i), 2)
|
||||
}
|
||||
for i := 0; i < 2; i++ {
|
||||
channels[i] = c.Take(ctx, c.Repeat(ctx, i), 2)
|
||||
}
|
||||
|
||||
chs := c.FanIn(ctx, channels...)
|
||||
chs := c.FanIn(ctx, channels...)
|
||||
|
||||
for v := range chs {
|
||||
fmt.Println(v) //1 1 0 0 or 0 0 1 1
|
||||
}
|
||||
for v := range chs {
|
||||
fmt.Println(v) //1 1 0 0 or 0 0 1 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="Generate">Generate</span>
|
||||
|
||||
<p>根据传入的值,生成channel.</p>
|
||||
@@ -166,7 +161,7 @@ func main() {
|
||||
```go
|
||||
func (c *Channel[T]) Generate(ctx context.Context, values ...T) <-chan T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -178,20 +173,20 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
c := concurrency.NewChannel[int]()
|
||||
intStream := c.Generate(ctx, 1, 2, 3)
|
||||
c := concurrency.NewChannel[int]()
|
||||
intStream := c.Generate(ctx, 1, 2, 3)
|
||||
|
||||
fmt.Println(<-intStream)
|
||||
fmt.Println(<-intStream)
|
||||
fmt.Println(<-intStream)
|
||||
fmt.Println(<-intStream)
|
||||
fmt.Println(<-intStream)
|
||||
fmt.Println(<-intStream)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
// 3
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
// 3
|
||||
}
|
||||
```
|
||||
|
||||
@@ -204,7 +199,7 @@ func main() {
|
||||
```go
|
||||
func (c *Channel[T]) Repeat(ctx context.Context, values ...T) <-chan T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -216,26 +211,24 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
c := concurrency.NewChannel[int]()
|
||||
intStream := c.Take(ctx, c.Repeat(ctx, 1, 2), 4)
|
||||
c := concurrency.NewChannel[int]()
|
||||
intStream := c.Take(ctx, c.Repeat(ctx, 1, 2), 4)
|
||||
|
||||
for v := range intStream {
|
||||
fmt.Println(v)
|
||||
}
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
// 1
|
||||
// 2
|
||||
for v := range intStream {
|
||||
fmt.Println(v)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
// 1
|
||||
// 2
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="RepeatFn">RepeatFn</span>
|
||||
|
||||
<p>返回一个channel,重复执行函数fn,并将结果放入返回的channel,直到取消上下文。</p>
|
||||
@@ -245,7 +238,7 @@ func main() {
|
||||
```go
|
||||
func (c *Channel[T]) RepeatFn(ctx context.Context, fn func() T) <-chan T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -257,28 +250,26 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
fn := func() string {
|
||||
return "hello"
|
||||
}
|
||||
fn := func() string {
|
||||
return "hello"
|
||||
}
|
||||
|
||||
c := concurrency.NewChannel[string]()
|
||||
intStream := c.Take(ctx, c.RepeatFn(ctx, fn), 3)
|
||||
c := concurrency.NewChannel[string]()
|
||||
intStream := c.Take(ctx, c.RepeatFn(ctx, fn), 3)
|
||||
|
||||
for v := range intStream {
|
||||
fmt.Println(v)
|
||||
}
|
||||
// Output:
|
||||
// hello
|
||||
// hello
|
||||
// hello
|
||||
for v := range intStream {
|
||||
fmt.Println(v)
|
||||
}
|
||||
// Output:
|
||||
// hello
|
||||
// hello
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Or">Or</span>
|
||||
|
||||
<p>将一个或多个channel读取到一个channel中,当任何读取channel关闭时将结束读取。</p>
|
||||
@@ -288,7 +279,7 @@ func main() {
|
||||
```go
|
||||
func (c *Channel[T]) Or(channels ...<-chan T) <-chan T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -300,31 +291,28 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
sig := func(after time.Duration) <-chan any {
|
||||
c := make(chan any)
|
||||
go func() {
|
||||
defer close(c)
|
||||
time.Sleep(after)
|
||||
}()
|
||||
return c
|
||||
}
|
||||
sig := func(after time.Duration) <-chan any {
|
||||
c := make(chan any)
|
||||
go func() {
|
||||
defer close(c)
|
||||
time.Sleep(after)
|
||||
}()
|
||||
return c
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
start := time.Now()
|
||||
|
||||
c := concurrency.NewChannel[any]()
|
||||
<-c.Or(
|
||||
sig(1*time.Second),
|
||||
sig(2*time.Second),
|
||||
sig(3*time.Second),
|
||||
)
|
||||
c := concurrency.NewChannel[any]()
|
||||
<-c.Or(
|
||||
sig(1*time.Second),
|
||||
sig(2*time.Second),
|
||||
sig(3*time.Second),
|
||||
)
|
||||
|
||||
fmt.Println("done after %v", time.Since(start)) //1.003s
|
||||
fmt.Println("done after %v", time.Since(start)) //1.003s
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="OrDone">OrDone</span>
|
||||
|
||||
<p>将一个channel读入另一个channel,直到取消上下文。</p>
|
||||
@@ -334,7 +322,7 @@ func main() {
|
||||
```go
|
||||
func (c *Channel[T]) OrDone(ctx context.Context, channel <-chan T) <-chan T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -346,25 +334,23 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
c := concurrency.NewChannel[int]()
|
||||
intStream := c.Take(ctx, c.Repeat(ctx, 1), 3)
|
||||
c := concurrency.NewChannel[int]()
|
||||
intStream := c.Take(ctx, c.Repeat(ctx, 1), 3)
|
||||
|
||||
for v := range c.OrDone(ctx, intStream) {
|
||||
fmt.Println(v)
|
||||
}
|
||||
// Output:
|
||||
// 1
|
||||
// 1
|
||||
// 1
|
||||
for v := range c.OrDone(ctx, intStream) {
|
||||
fmt.Println(v)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 1
|
||||
// 1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="Take">Take</span>
|
||||
|
||||
<p>返回一个channel,其值从另一个channel获取,直到取消上下文。</p>
|
||||
@@ -374,7 +360,7 @@ func main() {
|
||||
```go
|
||||
func (c *Channel[T]) Take(ctx context.Context, valueStream <-chan T, number int) <-chan T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -386,32 +372,31 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
numbers := make(chan int, 5)
|
||||
numbers <- 1
|
||||
numbers <- 2
|
||||
numbers <- 3
|
||||
numbers <- 4
|
||||
numbers <- 5
|
||||
defer close(numbers)
|
||||
numbers := make(chan int, 5)
|
||||
numbers <- 1
|
||||
numbers <- 2
|
||||
numbers <- 3
|
||||
numbers <- 4
|
||||
numbers <- 5
|
||||
defer close(numbers)
|
||||
|
||||
c := concurrency.NewChannel[int]()
|
||||
intStream := c.Take(ctx, numbers, 3)
|
||||
c := concurrency.NewChannel[int]()
|
||||
intStream := c.Take(ctx, numbers, 3)
|
||||
|
||||
for v := range intStream {
|
||||
fmt.Println(v)
|
||||
}
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
// 3
|
||||
for v := range intStream {
|
||||
fmt.Println(v)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
// 3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Tee">Tee</span>
|
||||
|
||||
<p>将一个channel分成两个channel,直到取消上下文。</p>
|
||||
@@ -421,7 +406,7 @@ func main() {
|
||||
```go
|
||||
func (c *Channel[T]) Tee(ctx context.Context, in <-chan T) (<-chan T, <-chan T)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -433,22 +418,22 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
c := concurrency.NewChannel[int]()
|
||||
intStream := c.Take(ctx, c.Repeat(ctx, 1), 2)
|
||||
c := concurrency.NewChannel[int]()
|
||||
intStream := c.Take(ctx, c.Repeat(ctx, 1), 2)
|
||||
|
||||
ch1, ch2 := c.Tee(ctx, intStream)
|
||||
ch1, ch2 := c.Tee(ctx, intStream)
|
||||
|
||||
for v := range ch1 {
|
||||
fmt.Println(v)
|
||||
fmt.Println(<-ch2)
|
||||
}
|
||||
// Output:
|
||||
// 1
|
||||
// 1
|
||||
// 1
|
||||
// 1
|
||||
for v := range ch1 {
|
||||
fmt.Println(v)
|
||||
fmt.Println(<-ch2)
|
||||
}
|
||||
// Output:
|
||||
// 1
|
||||
// 1
|
||||
// 1
|
||||
// 1
|
||||
}
|
||||
```
|
||||
@@ -57,41 +57,52 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
// bool
|
||||
fmt.Println(condition.Bool(false)) // false
|
||||
fmt.Println(condition.Bool(true)) // true
|
||||
// bool
|
||||
result1 := condition.Bool(false)
|
||||
result2 := condition.Bool(true)
|
||||
fmt.Println(result1) // false
|
||||
fmt.Println(result2) // true
|
||||
|
||||
// integer
|
||||
fmt.Println(condition.Bool(0)) // false
|
||||
fmt.Println(condition.Bool(1)) // true
|
||||
// integer
|
||||
result3 := condition.Bool(0)
|
||||
result4 := condition.Bool(1)
|
||||
fmt.Println(result3) // false
|
||||
fmt.Println(result4) // true
|
||||
|
||||
// float
|
||||
fmt.Println(condition.Bool(0.0)) // false
|
||||
fmt.Println(condition.Bool(0.1)) // true
|
||||
// string
|
||||
result5 := condition.Bool("")
|
||||
result6 := condition.Bool(" ")
|
||||
fmt.Println(result5) // false
|
||||
fmt.Println(result6) // true
|
||||
|
||||
// string
|
||||
fmt.Println(condition.Bool("")) // false
|
||||
fmt.Println(condition.Bool(" ")) // true
|
||||
fmt.Println(condition.Bool("0")) // true
|
||||
// slice
|
||||
nums := []int{}
|
||||
result7 := condition.Bool(nums)
|
||||
|
||||
// slice
|
||||
var nums [2]int
|
||||
fmt.Println(condition.Bool(nums)) // false
|
||||
nums = [2]int{0, 1}
|
||||
fmt.Println(condition.Bool(nums)) // true
|
||||
nums = append(nums, 1, 2)
|
||||
result8 := condition.Bool(nums)
|
||||
fmt.Println(result7) // false
|
||||
fmt.Println(result8) // true
|
||||
|
||||
// map
|
||||
fmt.Println(condition.Bool(map[string]string{})) // false
|
||||
fmt.Println(condition.Bool(map[string]string{"a": "a"})) // true
|
||||
// struct
|
||||
result9 = condition.Bool(struct{}{})
|
||||
fmt.Println(result8) // false
|
||||
|
||||
// struct
|
||||
fmt.Println(condition.Bool(struct{}{})) // false
|
||||
fmt.Println(condition.Bool(time.Now())) // true
|
||||
|
||||
// Output:
|
||||
// false
|
||||
// true
|
||||
// false
|
||||
// true
|
||||
// false
|
||||
// true
|
||||
// false
|
||||
// true
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="And">And</span>
|
||||
<p>Returns true if both a and b are truthy.</p>
|
||||
|
||||
@@ -111,10 +122,10 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(condition.And(0, 1)) // false
|
||||
fmt.Println(condition.And(0, "")) // false
|
||||
fmt.Println(condition.And(0, "0")) // false
|
||||
fmt.Println(condition.And(1, "0")) // true
|
||||
fmt.Println(condition.And(0, 1)) // false
|
||||
fmt.Println(condition.And(0, "")) // false
|
||||
fmt.Println(condition.And(0, "0")) // false
|
||||
fmt.Println(condition.And(1, "0")) // true
|
||||
}
|
||||
```
|
||||
|
||||
@@ -139,10 +150,10 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(condition.Or(0, "")) // false
|
||||
fmt.Println(condition.Or(0, 1)) // true
|
||||
fmt.Println(condition.Or(0, "0")) // true
|
||||
fmt.Println(condition.Or(1, "0")) // true
|
||||
fmt.Println(condition.Or(0, "")) // false
|
||||
fmt.Println(condition.Or(0, 1)) // true
|
||||
fmt.Println(condition.Or(0, "0")) // true
|
||||
fmt.Println(condition.Or(1, "0")) // true
|
||||
}
|
||||
```
|
||||
|
||||
@@ -167,10 +178,10 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(condition.Xor(0, 0)) // false
|
||||
fmt.Println(condition.Xor(0, 1)) // true
|
||||
fmt.Println(condition.Xor(1, 0)) // true
|
||||
fmt.Println(condition.Xor(1, 1)) // false
|
||||
fmt.Println(condition.Xor(0, 0)) // false
|
||||
fmt.Println(condition.Xor(0, 1)) // true
|
||||
fmt.Println(condition.Xor(1, 0)) // true
|
||||
fmt.Println(condition.Xor(1, 1)) // false
|
||||
}
|
||||
```
|
||||
|
||||
@@ -195,10 +206,10 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(condition.Nor(0, 0)) // true
|
||||
fmt.Println(condition.Nor(0, 1)) // false
|
||||
fmt.Println(condition.Nor(1, 0)) // false
|
||||
fmt.Println(condition.Nor(1, 1)) // false
|
||||
fmt.Println(condition.Nor(0, 0)) // true
|
||||
fmt.Println(condition.Nor(0, 1)) // false
|
||||
fmt.Println(condition.Nor(1, 0)) // false
|
||||
fmt.Println(condition.Nor(1, 1)) // false
|
||||
}
|
||||
```
|
||||
|
||||
@@ -222,10 +233,10 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(condition.Xnor(0, 0)) // true
|
||||
fmt.Println(condition.Xnor(0, 1)) // false
|
||||
fmt.Println(condition.Xnor(1, 0)) // false
|
||||
fmt.Println(condition.Xnor(1, 1)) // true
|
||||
fmt.Println(condition.Xnor(0, 0)) // true
|
||||
fmt.Println(condition.Xnor(0, 1)) // false
|
||||
fmt.Println(condition.Xnor(1, 0)) // false
|
||||
fmt.Println(condition.Xnor(1, 1)) // true
|
||||
}
|
||||
```
|
||||
|
||||
@@ -249,10 +260,10 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(condition.Nand(0, 0)) // true
|
||||
fmt.Println(condition.Nand(0, 1)) // true
|
||||
fmt.Println(condition.Nand(1, 0)) // true
|
||||
fmt.Println(condition.Nand(1, 1)) // false
|
||||
fmt.Println(condition.Nand(0, 0)) // true
|
||||
fmt.Println(condition.Nand(0, 1)) // true
|
||||
fmt.Println(condition.Nand(1, 0)) // true
|
||||
fmt.Println(condition.Nand(1, 1)) // false
|
||||
}
|
||||
```
|
||||
|
||||
@@ -277,10 +288,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
trueValue := "1"
|
||||
falseValue := "0"
|
||||
conditionTrue := 2 > 1
|
||||
result1 := condition.TernaryOperator(conditionTrue, 0, 1)
|
||||
|
||||
fmt.Println(condition.TernaryOperator(true, trueValue, falseValue)) // "1"
|
||||
conditionFalse := 2 > 3
|
||||
result2 := condition.TernaryOperator(conditionFalse, 0, 1)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// 0
|
||||
// 1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ slices和map的length大于0时,返回true,否则返回false<br/>
|
||||
```go
|
||||
func Bool[T any](value T) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -56,41 +56,51 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
// bool
|
||||
fmt.Println(condition.Bool(false)) // false
|
||||
fmt.Println(condition.Bool(true)) // true
|
||||
// bool
|
||||
result1 := condition.Bool(false)
|
||||
result2 := condition.Bool(true)
|
||||
fmt.Println(result1) // false
|
||||
fmt.Println(result2) // true
|
||||
|
||||
// integer
|
||||
fmt.Println(condition.Bool(0)) // false
|
||||
fmt.Println(condition.Bool(1)) // true
|
||||
// integer
|
||||
result3 := condition.Bool(0)
|
||||
result4 := condition.Bool(1)
|
||||
fmt.Println(result3) // false
|
||||
fmt.Println(result4) // true
|
||||
|
||||
// float
|
||||
fmt.Println(condition.Bool(0.0)) // false
|
||||
fmt.Println(condition.Bool(0.1)) // true
|
||||
// string
|
||||
result5 := condition.Bool("")
|
||||
result6 := condition.Bool(" ")
|
||||
fmt.Println(result5) // false
|
||||
fmt.Println(result6) // true
|
||||
|
||||
// string
|
||||
fmt.Println(condition.Bool("")) // false
|
||||
fmt.Println(condition.Bool(" ")) // true
|
||||
fmt.Println(condition.Bool("0")) // true
|
||||
// slice
|
||||
nums := []int{}
|
||||
result7 := condition.Bool(nums)
|
||||
|
||||
// slice
|
||||
var nums [2]int
|
||||
fmt.Println(condition.Bool(nums)) // false
|
||||
nums = [2]int{0, 1}
|
||||
fmt.Println(condition.Bool(nums)) // true
|
||||
nums = append(nums, 1, 2)
|
||||
result8 := condition.Bool(nums)
|
||||
fmt.Println(result7) // false
|
||||
fmt.Println(result8) // true
|
||||
|
||||
// map
|
||||
fmt.Println(condition.Bool(map[string]string{})) // false
|
||||
fmt.Println(condition.Bool(map[string]string{"a": "a"})) // true
|
||||
// struct
|
||||
result9 = condition.Bool(struct{}{})
|
||||
fmt.Println(result8) // false
|
||||
|
||||
// struct
|
||||
fmt.Println(condition.Bool(struct{}{})) // false
|
||||
fmt.Println(condition.Bool(time.Now())) // true
|
||||
|
||||
// Output:
|
||||
// false
|
||||
// true
|
||||
// false
|
||||
// true
|
||||
// false
|
||||
// true
|
||||
// false
|
||||
// true
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="And">And</span>
|
||||
<p>逻辑且操作,当切仅当a和b都为true时返回true</p>
|
||||
|
||||
@@ -99,7 +109,7 @@ func main() {
|
||||
```go
|
||||
func And[T, U any](a T, b U) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -110,15 +120,13 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(condition.And(0, 1)) // false
|
||||
fmt.Println(condition.And(0, "")) // false
|
||||
fmt.Println(condition.And(0, "0")) // false
|
||||
fmt.Println(condition.And(1, "0")) // true
|
||||
fmt.Println(condition.And(0, 1)) // false
|
||||
fmt.Println(condition.And(0, "")) // false
|
||||
fmt.Println(condition.And(0, "0")) // false
|
||||
fmt.Println(condition.And(1, "0")) // true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Or">Or</span>
|
||||
<p>逻辑或操作,当切仅当a和b都为false时返回false</p>
|
||||
|
||||
@@ -127,7 +135,7 @@ func main() {
|
||||
```go
|
||||
func Or[T, U any](a T, b U) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -138,15 +146,13 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(condition.Or(0, "")) // false
|
||||
fmt.Println(condition.Or(0, 1)) // true
|
||||
fmt.Println(condition.Or(0, "0")) // true
|
||||
fmt.Println(condition.Or(1, "0")) // true
|
||||
fmt.Println(condition.Or(0, "")) // false
|
||||
fmt.Println(condition.Or(0, 1)) // true
|
||||
fmt.Println(condition.Or(0, "0")) // true
|
||||
fmt.Println(condition.Or(1, "0")) // true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Xor">Xor</span>
|
||||
<p>逻辑异或操作,a和b相同返回false,a和b不相同返回true</p>
|
||||
|
||||
@@ -155,7 +161,7 @@ func main() {
|
||||
```go
|
||||
func Xor[T, U any](a T, b U) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -166,15 +172,13 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(condition.Xor(0, 0)) // false
|
||||
fmt.Println(condition.Xor(0, 1)) // true
|
||||
fmt.Println(condition.Xor(1, 0)) // true
|
||||
fmt.Println(condition.Xor(1, 1)) // false
|
||||
fmt.Println(condition.Xor(0, 0)) // false
|
||||
fmt.Println(condition.Xor(0, 1)) // true
|
||||
fmt.Println(condition.Xor(1, 0)) // true
|
||||
fmt.Println(condition.Xor(1, 1)) // false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Nor">Nor</span>
|
||||
<p>异或的取反操作</p>
|
||||
|
||||
@@ -183,7 +187,7 @@ func main() {
|
||||
```go
|
||||
func Nor[T, U any](a T, b U) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -194,15 +198,13 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(condition.Nor(0, 0)) // true
|
||||
fmt.Println(condition.Nor(0, 1)) // false
|
||||
fmt.Println(condition.Nor(1, 0)) // false
|
||||
fmt.Println(condition.Nor(1, 1)) // false
|
||||
fmt.Println(condition.Nor(0, 0)) // true
|
||||
fmt.Println(condition.Nor(0, 1)) // false
|
||||
fmt.Println(condition.Nor(1, 0)) // false
|
||||
fmt.Println(condition.Nor(1, 1)) // false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Xnor">Xnor</span>
|
||||
<p>如果a和b都是真的或a和b均是假的,则返回true。</p>
|
||||
|
||||
@@ -211,7 +213,7 @@ func main() {
|
||||
```go
|
||||
func Xnor[T, U any](a T, b U) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -222,10 +224,10 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(condition.Xnor(0, 0)) // true
|
||||
fmt.Println(condition.Xnor(0, 1)) // false
|
||||
fmt.Println(condition.Xnor(1, 0)) // false
|
||||
fmt.Println(condition.Xnor(1, 1)) // true
|
||||
fmt.Println(condition.Xnor(0, 0)) // true
|
||||
fmt.Println(condition.Xnor(0, 1)) // false
|
||||
fmt.Println(condition.Xnor(1, 0)) // false
|
||||
fmt.Println(condition.Xnor(1, 1)) // true
|
||||
}
|
||||
```
|
||||
|
||||
@@ -237,7 +239,7 @@ func main() {
|
||||
```go
|
||||
func Nand[T, U any](a T, b U) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -248,15 +250,13 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(condition.Nand(0, 0)) // true
|
||||
fmt.Println(condition.Nand(0, 1)) // true
|
||||
fmt.Println(condition.Nand(1, 0)) // true
|
||||
fmt.Println(condition.Nand(1, 1)) // false
|
||||
fmt.Println(condition.Nand(0, 0)) // true
|
||||
fmt.Println(condition.Nand(0, 1)) // true
|
||||
fmt.Println(condition.Nand(1, 0)) // true
|
||||
fmt.Println(condition.Nand(1, 1)) // false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="TernaryOperator">TernaryOperator</span>
|
||||
<p>三元运算符</p>
|
||||
|
||||
@@ -265,7 +265,7 @@ func main() {
|
||||
```go
|
||||
func TernaryOperator[T, U any](isTrue T, ifValue U, elseValue U) U
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -276,10 +276,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
trueValue := "1"
|
||||
falseValue := "0"
|
||||
conditionTrue := 2 > 1
|
||||
result1 := condition.TernaryOperator(conditionTrue, 0, 1)
|
||||
|
||||
fmt.Println(condition.TernaryOperator(true, trueValue, falseValue)) // "1"
|
||||
conditionFalse := 2 > 3
|
||||
result2 := condition.TernaryOperator(conditionFalse, 0, 1)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// 0
|
||||
// 1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -40,8 +40,6 @@ import (
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
|
||||
### <span id="ColorHexToRGB">ColorHexToRGB</span>
|
||||
<p>Convert color hex to color rgb.</p>
|
||||
|
||||
@@ -63,12 +61,14 @@ import (
|
||||
func main() {
|
||||
colorHex := "#003366"
|
||||
r, g, b := convertor.ColorHexToRGB(colorHex)
|
||||
fmt.Println(r, g, b) //0,51,102
|
||||
|
||||
fmt.Println(r, g, b)
|
||||
|
||||
// Output:
|
||||
// 0 51 102
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ColorRGBToHex">ColorRGBToHex</span>
|
||||
|
||||
<p>Convert color rgb to color hex.</p>
|
||||
@@ -92,14 +92,15 @@ func main() {
|
||||
r := 0
|
||||
g := 51
|
||||
b := 102
|
||||
colorHex := convertor.ColorRGBToHex(r, g, b)
|
||||
colorHex := ColorRGBToHex(r, g, b)
|
||||
|
||||
fmt.Println(colorHex) //#003366
|
||||
fmt.Println(colorHex)
|
||||
|
||||
// Output:
|
||||
// #003366
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToBool">ToBool</span>
|
||||
|
||||
<p>Convert string to bool. Use strconv.ParseBool.</p>
|
||||
@@ -120,22 +121,26 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
v1, _ := convertor.ToBool("1")
|
||||
fmt.Println(v1) //true
|
||||
cases := []string{"1", "true", "True", "false", "False", "0", "123", "0.0", "abc"}
|
||||
|
||||
v2, _ := convertor.ToBool("true")
|
||||
fmt.Println(v2) //true
|
||||
for i := 0; i < len(cases); i++ {
|
||||
result, _ := convertor.ToBool(cases[i])
|
||||
fmt.Println(result)
|
||||
}
|
||||
|
||||
v3, _ := convertor.ToBool("True")
|
||||
fmt.Println(v3) //true
|
||||
|
||||
v4, _ := convertor.ToBool("123")
|
||||
fmt.Println(v4) //false
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
// false
|
||||
// false
|
||||
// false
|
||||
// false
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToBytes">ToBytes</span>
|
||||
|
||||
<p>Convert value to byte slice.</p>
|
||||
@@ -156,16 +161,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
bytesData, err := convertor.ToBytes("0")
|
||||
bytesData, err := convertor.ToBytes("abc")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println(bytesData) //[]bytes{3, 4, 0, 0}
|
||||
|
||||
fmt.Println(bytesData)
|
||||
|
||||
// Output:
|
||||
// [97 98 99]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToChar">ToChar</span>
|
||||
|
||||
<p>Convert string to char slice.</p>
|
||||
@@ -186,18 +193,21 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
chars := convertor.ToChar("")
|
||||
fmt.Println(chars) //[]string{""}
|
||||
result1 := convertor.ToChar("")
|
||||
result2 := convertor.ToChar("abc")
|
||||
result3 := convertor.ToChar("1 2#3")
|
||||
|
||||
chars = convertor.ToChar("abc")
|
||||
fmt.Println(chars) //[]string{"a", "b", "c"}
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
chars = convertor.ToChar("1 2#3")
|
||||
fmt.Println(chars) //[]string{"1", " ", "2", "#", "3"}
|
||||
// Output:
|
||||
// []
|
||||
// [a b c]
|
||||
// [1 2 # 3]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="ToChannel">ToChannel</span>
|
||||
|
||||
<p>Convert a collection of elements to a read-only channel.</p>
|
||||
@@ -219,23 +229,21 @@ import (
|
||||
|
||||
func main() {
|
||||
ch := convertor.ToChannel([]int{1, 2, 3})
|
||||
result1 := <-ch
|
||||
result2 := <-ch
|
||||
result3 := <-ch
|
||||
|
||||
val1, _ := <-ch
|
||||
fmt.Println(val1) //1
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
val2, _ := <-ch
|
||||
fmt.Println(val2) //2
|
||||
|
||||
val3, _ := <-ch
|
||||
fmt.Println(val3) //3
|
||||
|
||||
_, ok := <-ch
|
||||
fmt.Println(ok) //false
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
// 3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToFloat">ToFloat</span>
|
||||
|
||||
<p>Convert value to a float64 value. If param is a invalid floatable, will return 0.0 and error. </p>
|
||||
@@ -256,19 +264,30 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
v, err := convertor.ToFloat("")
|
||||
if err != nil {
|
||||
fmt.Println(err) //strconv.ParseFloat: parsing "": invalid syntax
|
||||
}
|
||||
fmt.Println(v) //0
|
||||
result1, _ := convertor.ToFloat("")
|
||||
result2, err := convertor.ToFloat("abc")
|
||||
result3, _ := convertor.ToFloat("-1")
|
||||
result4, _ := convertor.ToFloat("-.11")
|
||||
result5, _ := convertor.ToFloat("1.23e3")
|
||||
result6, _ := convertor.ToFloat(true)
|
||||
|
||||
v, _ = convertor.ToFloat("-.11")
|
||||
fmt.Println(v) //-0.11
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2, err)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
fmt.Println(result6)
|
||||
|
||||
// Output:
|
||||
// 0
|
||||
// 0 strconv.ParseFloat: parsing "": invalid syntax
|
||||
// -1
|
||||
// -0.11
|
||||
// 1230
|
||||
// 0
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToInt">ToInt</span>
|
||||
|
||||
<p>Convert value to a int64 value. If param is a invalid intable, will return 0 and error. </p>
|
||||
@@ -289,19 +308,27 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
v, err := convertor.ToInt("")
|
||||
if err != nil {
|
||||
fmt.Println(err) //strconv.ParseInt: parsing "": invalid syntax
|
||||
}
|
||||
fmt.Println(v) //0
|
||||
result1, _ := convertor.ToInt("123")
|
||||
result2, _ := convertor.ToInt("-123")
|
||||
result3, _ := convertor.ToInt(float64(12.3))
|
||||
result4, err := convertor.ToInt("abc")
|
||||
result5, _ := convertor.ToInt(true)
|
||||
|
||||
v, _ = convertor.ToFloat(1.12)
|
||||
fmt.Println(v) //1
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4, err)
|
||||
fmt.Println(result5)
|
||||
|
||||
// Output:
|
||||
// 123
|
||||
// -123
|
||||
// 12
|
||||
// 0 strconv.ParseInt: parsing "": invalid syntax
|
||||
// 0
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToJson">ToJson</span>
|
||||
|
||||
<p>Convert interface to json string. If param can't be converted, will return "" and error. </p>
|
||||
@@ -322,14 +349,20 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
var aMap = map[string]int{"a": 1, "b": 2, "c": 3}
|
||||
jsonStr, _ := convertor.ToJson(aMap)
|
||||
fmt.Printf("%q", jsonStr) //"{\"a\":1,\"b\":2,\"c\":3}"
|
||||
aMap := map[string]int{"a": 1, "b": 2, "c": 3}
|
||||
result, err := ToJson(aMap)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("%v", err)
|
||||
}
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// {"a":1,"b":2,"c":3}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToMap">ToMap</span>
|
||||
|
||||
<p>Convert a slice of structs to a map based on iteratee function. </p>
|
||||
@@ -358,16 +391,18 @@ func main() {
|
||||
{name: "Hello", code: 100},
|
||||
{name: "Hi", code: 101},
|
||||
}
|
||||
|
||||
result := convertor.ToMap(messages, func(msg Message) (int, string) {
|
||||
return msg.code, msg.name
|
||||
})
|
||||
|
||||
fmt.Println(result) //{100: "Hello", 101: "Hi"}
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// map[100:Hello 101:Hi]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToPointer">ToPointer</span>
|
||||
|
||||
<p>Returns a pointer to passed value. </p>
|
||||
@@ -389,11 +424,13 @@ import (
|
||||
|
||||
func main() {
|
||||
result := convertor.ToPointer(123)
|
||||
fmt.Println(*result) //123
|
||||
fmt.Println(*result)
|
||||
|
||||
// Output:
|
||||
// 123
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="ToString">ToString</span>
|
||||
|
||||
<p>ToString convert value to string, for number, string, []byte, will convert to string. For other type (slice, map, array, struct) will call json.Marshal</p>
|
||||
@@ -414,13 +451,33 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Printf("%q", convertor.ToString(1)) //"1"
|
||||
fmt.Printf("%q", convertor.ToString(1.1)) //"1.1"
|
||||
fmt.Printf("%q", convertor.ToString([]int{1, 2, 3})) //"[1,2,3]"
|
||||
result1 := convertor.ToString("")
|
||||
result2 := convertor.ToString(nil)
|
||||
result3 := convertor.ToString(0)
|
||||
result4 := convertor.ToString(1.23)
|
||||
result5 := convertor.ToString(true)
|
||||
result6 := convertor.ToString(false)
|
||||
result7 := convertor.ToString([]int{1, 2, 3})
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
fmt.Println(result6)
|
||||
fmt.Println(result7)
|
||||
|
||||
// Output:
|
||||
//
|
||||
//
|
||||
// 0
|
||||
// 1.23
|
||||
// true
|
||||
// false
|
||||
// [1,2,3]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="StructToMap">StructToMap</span>
|
||||
|
||||
<p>Convert struct to map, only convert exported field, struct field tag `json` should be set.</p>
|
||||
@@ -451,12 +508,13 @@ func main() {
|
||||
}
|
||||
pm, _ := convertor.StructToMap(p)
|
||||
|
||||
fmt.Printf("type: %T, value: %s", pm, pm) //type: map[string]interface {}, value: map[name:test]
|
||||
fmt.Println(pm)
|
||||
|
||||
// Output:
|
||||
// map[name:test]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="MapToSlice">MapToSlice</span>
|
||||
|
||||
<p>Convert a map to a slice based on iteratee function.</p>
|
||||
@@ -508,12 +566,13 @@ import (
|
||||
|
||||
func main() {
|
||||
byteData, _ := convertor.EncodeByte("abc")
|
||||
fmt.Println(byteData) //[]byte{6, 12, 0, 3, 97, 98, 99}
|
||||
fmt.Println(byteData)
|
||||
|
||||
// Output:
|
||||
// [6 12 0 3 97 98 99]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="DecodeByte">DecodeByte</span>
|
||||
|
||||
<p>Decode byte data to target object. target should be a pointer instance.</p>
|
||||
@@ -535,8 +594,16 @@ import (
|
||||
|
||||
func main() {
|
||||
var result string
|
||||
byteData := []byte{6, 12, 0, 3, 97, 98, 99}
|
||||
convertor.DecodeByte(byteData, &result)
|
||||
fmt.Println(result) //"abc"
|
||||
byteData := []byte{6, 12, 0, 3, 97, 98, 99}
|
||||
|
||||
err := convertor.DecodeByte(byteData, &result)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// abc
|
||||
}
|
||||
```
|
||||
@@ -43,16 +43,15 @@ import (
|
||||
## 文档
|
||||
|
||||
|
||||
|
||||
### <span id="ColorHexToRGB">ColorHexToRGB</span>
|
||||
<p>颜色值十六进制转rgb</p>
|
||||
<p>颜色值十六进制转rgb。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ColorHexToRGB(colorHex string) (red, green, blue int)
|
||||
```
|
||||
<b>列子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -65,22 +64,24 @@ import (
|
||||
func main() {
|
||||
colorHex := "#003366"
|
||||
r, g, b := convertor.ColorHexToRGB(colorHex)
|
||||
fmt.Println(r, g, b) //0,51,102
|
||||
|
||||
fmt.Println(r, g, b)
|
||||
|
||||
// Output:
|
||||
// 0 51 102
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ColorRGBToHex">ColorRGBToHex</span>
|
||||
|
||||
<p>颜色值rgb转十六进制</p>
|
||||
<p>颜色值rgb转十六进制。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ColorRGBToHex(red, green, blue int) string
|
||||
```
|
||||
<b>列子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -94,24 +95,25 @@ func main() {
|
||||
r := 0
|
||||
g := 51
|
||||
b := 102
|
||||
colorHex := convertor.ColorRGBToHex(r, g, b)
|
||||
colorHex := ColorRGBToHex(r, g, b)
|
||||
|
||||
fmt.Println(colorHex) //#003366
|
||||
fmt.Println(colorHex)
|
||||
|
||||
// Output:
|
||||
// #003366
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToBool">ToBool</span>
|
||||
|
||||
<p>字符串转布尔类型,使用strconv.ParseBool</p>
|
||||
<p>字符串转布尔类型,使用strconv.ParseBool。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ToBool(s string) (bool, error)
|
||||
```
|
||||
<b>列子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -122,32 +124,36 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
v1, _ := convertor.ToBool("1")
|
||||
fmt.Println(v1) //true
|
||||
cases := []string{"1", "true", "True", "false", "False", "0", "123", "0.0", "abc"}
|
||||
|
||||
v2, _ := convertor.ToBool("true")
|
||||
fmt.Println(v2) //true
|
||||
for i := 0; i < len(cases); i++ {
|
||||
result, _ := convertor.ToBool(cases[i])
|
||||
fmt.Println(result)
|
||||
}
|
||||
|
||||
v3, _ := convertor.ToBool("True")
|
||||
fmt.Println(v3) //true
|
||||
|
||||
v4, _ := convertor.ToBool("123")
|
||||
fmt.Println(v4) //false
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
// false
|
||||
// false
|
||||
// false
|
||||
// false
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToBytes">ToBytes</span>
|
||||
|
||||
<p>interface转字节切片.</p>
|
||||
<p>Interface转字节切片。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ToBytes(data any) ([]byte, error)
|
||||
```
|
||||
<b>列子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -158,26 +164,28 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
bytesData, err := convertor.ToBytes("0")
|
||||
bytesData, err := convertor.ToBytes("abc")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println(bytesData) //[]bytes{3, 4, 0, 0}
|
||||
|
||||
fmt.Println(bytesData)
|
||||
|
||||
// Output:
|
||||
// [97 98 99]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToChar">ToChar</span>
|
||||
|
||||
<p>字符串转字符切片</p>
|
||||
<p>字符串转字符切片。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ToChar(s string) []string
|
||||
```
|
||||
<b>列子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -188,29 +196,31 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
chars := convertor.ToChar("")
|
||||
fmt.Println(chars) //[]string{""}
|
||||
result1 := convertor.ToChar("")
|
||||
result2 := convertor.ToChar("abc")
|
||||
result3 := convertor.ToChar("1 2#3")
|
||||
|
||||
chars = convertor.ToChar("abc")
|
||||
fmt.Println(chars) //[]string{"a", "b", "c"}
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
chars = convertor.ToChar("1 2#3")
|
||||
fmt.Println(chars) //[]string{"1", " ", "2", "#", "3"}
|
||||
// Output:
|
||||
// []
|
||||
// [a b c]
|
||||
// [1 2 # 3]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToChannel">ToChannel</span>
|
||||
|
||||
<p>将切片转为只读channel</p>
|
||||
<p>将切片转为只读channel。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ToChannel[T any](array []T) <-chan T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -222,33 +232,31 @@ import (
|
||||
|
||||
func main() {
|
||||
ch := convertor.ToChannel([]int{1, 2, 3})
|
||||
result1 := <-ch
|
||||
result2 := <-ch
|
||||
result3 := <-ch
|
||||
|
||||
val1, _ := <-ch
|
||||
fmt.Println(val1) //1
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
val2, _ := <-ch
|
||||
fmt.Println(val2) //2
|
||||
|
||||
val3, _ := <-ch
|
||||
fmt.Println(val3) //3
|
||||
|
||||
_, ok := <-ch
|
||||
fmt.Println(ok) //false
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
// 3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToFloat">ToFloat</span>
|
||||
|
||||
<p>将interface转成float64类型,如果参数无法转换,会返回0和error</p>
|
||||
<p>将interface转成float64类型,如果参数无法转换,会返回0和error。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ToFloat(value any) (float64, error)
|
||||
```
|
||||
<b>列子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -259,29 +267,40 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
v, err := convertor.ToFloat("")
|
||||
if err != nil {
|
||||
fmt.Println(err) //strconv.ParseFloat: parsing "": invalid syntax
|
||||
}
|
||||
fmt.Println(v) //0
|
||||
result1, _ := convertor.ToFloat("")
|
||||
result2, err := convertor.ToFloat("abc")
|
||||
result3, _ := convertor.ToFloat("-1")
|
||||
result4, _ := convertor.ToFloat("-.11")
|
||||
result5, _ := convertor.ToFloat("1.23e3")
|
||||
result6, _ := convertor.ToFloat(true)
|
||||
|
||||
v, _ = convertor.ToFloat("-.11")
|
||||
fmt.Println(v) //-0.11
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2, err)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
fmt.Println(result6)
|
||||
|
||||
// Output:
|
||||
// 0
|
||||
// 0 strconv.ParseFloat: parsing "": invalid syntax
|
||||
// -1
|
||||
// -0.11
|
||||
// 1230
|
||||
// 0
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToInt">ToInt</span>
|
||||
|
||||
<p>将interface转成int64类型,如果参数无法转换,会返回0和error</p>
|
||||
<p>将interface转成int64类型,如果参数无法转换,会返回0和error。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ToInt(value any) (int64, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -292,29 +311,37 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
v, err := convertor.ToInt("")
|
||||
if err != nil {
|
||||
fmt.Println(err) //strconv.ParseInt: parsing "": invalid syntax
|
||||
}
|
||||
fmt.Println(v) //0
|
||||
result1, _ := convertor.ToInt("123")
|
||||
result2, _ := convertor.ToInt("-123")
|
||||
result3, _ := convertor.ToInt(float64(12.3))
|
||||
result4, err := convertor.ToInt("abc")
|
||||
result5, _ := convertor.ToInt(true)
|
||||
|
||||
v, _ = convertor.ToFloat(1.12)
|
||||
fmt.Println(v) //1
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4, err)
|
||||
fmt.Println(result5)
|
||||
|
||||
// Output:
|
||||
// 123
|
||||
// -123
|
||||
// 12
|
||||
// 0 strconv.ParseInt: parsing "": invalid syntax
|
||||
// 0
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToJson">ToJson</span>
|
||||
|
||||
<p>将interface转成json字符串,如果参数无法转换,会返回""和error</p>
|
||||
<p>将interface转成json字符串,如果参数无法转换,会返回""和error。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ToJson(value any) (string, error)
|
||||
```
|
||||
<b>列子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -325,24 +352,30 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
var aMap = map[string]int{"a": 1, "b": 2, "c": 3}
|
||||
jsonStr, _ := convertor.ToJson(aMap)
|
||||
fmt.Printf("%q", jsonStr) //"{\"a\":1,\"b\":2,\"c\":3}"
|
||||
aMap := map[string]int{"a": 1, "b": 2, "c": 3}
|
||||
result, err := ToJson(aMap)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("%v", err)
|
||||
}
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// {"a":1,"b":2,"c":3}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToMap">ToMap</span>
|
||||
|
||||
<p>将切片转为map</p>
|
||||
<p>将切片转为map。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ToMap[T any, K comparable, V any](array []T, iteratee func(T) (K, V)) map[K]V
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -361,26 +394,28 @@ func main() {
|
||||
{name: "Hello", code: 100},
|
||||
{name: "Hi", code: 101},
|
||||
}
|
||||
|
||||
result := convertor.ToMap(messages, func(msg Message) (int, string) {
|
||||
return msg.code, msg.name
|
||||
})
|
||||
|
||||
fmt.Println(result) //{100: "Hello", 101: "Hi"}
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// map[100:Hello 101:Hi]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToPointer">ToPointer</span>
|
||||
|
||||
<p>返回传入值的指针</p>
|
||||
<p>返回传入值的指针。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ToPointer[T any](value T) *T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -392,22 +427,23 @@ import (
|
||||
|
||||
func main() {
|
||||
result := convertor.ToPointer(123)
|
||||
fmt.Println(*result) //123
|
||||
fmt.Println(*result)
|
||||
|
||||
// Output:
|
||||
// 123
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToString">ToString</span>
|
||||
|
||||
<p>将值转换为字符串,对于数字、字符串、[]byte,将转换为字符串。 对于其他类型(切片、映射、数组、结构)将调用 json.Marshal</p>
|
||||
<p>将值转换为字符串,对于数字、字符串、[]byte,将转换为字符串。 对于其他类型(切片、映射、数组、结构体)将调用 json.Marshal</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ToString(value any) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -418,24 +454,43 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Printf("%q", convertor.ToString(1)) //"1"
|
||||
fmt.Printf("%q", convertor.ToString(1.1)) //"1.1"
|
||||
fmt.Printf("%q", convertor.ToString([]int{1, 2, 3})) //"[1,2,3]"
|
||||
result1 := convertor.ToString("")
|
||||
result2 := convertor.ToString(nil)
|
||||
result3 := convertor.ToString(0)
|
||||
result4 := convertor.ToString(1.23)
|
||||
result5 := convertor.ToString(true)
|
||||
result6 := convertor.ToString(false)
|
||||
result7 := convertor.ToString([]int{1, 2, 3})
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
fmt.Println(result6)
|
||||
fmt.Println(result7)
|
||||
|
||||
// Output:
|
||||
//
|
||||
//
|
||||
// 0
|
||||
// 1.23
|
||||
// true
|
||||
// false
|
||||
// [1,2,3]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="StructToMap">StructToMap</span>
|
||||
|
||||
<p>将struct转成map,只会转换struct中可导出的字段。struct中导出字段需要设置json tag标记</p>
|
||||
<p>将struct转成map,只会转换struct中可导出的字段。struct中导出字段需要设置json tag标记。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func StructToMap(value any) (map[string]any, error)
|
||||
```
|
||||
<b>列子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -456,22 +511,23 @@ func main() {
|
||||
}
|
||||
pm, _ := convertor.StructToMap(p)
|
||||
|
||||
fmt.Printf("type: %T, value: %s", pm, pm) //type: map[string]interface {}, value: map[name:test]
|
||||
fmt.Println(pm)
|
||||
|
||||
// Output:
|
||||
// map[name:test]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="MapToSlice">MapToSlice</span>
|
||||
|
||||
<p>map中key和value执行函数iteratee后,转为切片</p>
|
||||
<p>map中key和value执行函数iteratee后,转为切片。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func MapToSlice[T any, K comparable, V any](aMap map[K]V, iteratee func(K, V) T) []T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -491,18 +547,16 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="EncodeByte">EncodeByte</span>
|
||||
|
||||
<p>将data编码成字节切片</p>
|
||||
<p>将data编码成字节切片。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func EncodeByte(data any) ([]byte, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -514,22 +568,23 @@ import (
|
||||
|
||||
func main() {
|
||||
byteData, _ := convertor.EncodeByte("abc")
|
||||
fmt.Println(byteData) //[]byte{6, 12, 0, 3, 97, 98, 99}
|
||||
fmt.Println(byteData)
|
||||
|
||||
// Output:
|
||||
// [6 12 0 3 97 98 99]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="DecodeByte">DecodeByte</span>
|
||||
|
||||
<p>解码字节切片到目标对象,目标对象需要传入一个指针实例</p>
|
||||
<p>解码字节切片到目标对象,目标对象需要传入一个指针实例。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func DecodeByte(data []byte, target any) error
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -541,8 +596,16 @@ import (
|
||||
|
||||
func main() {
|
||||
var result string
|
||||
byteData := []byte{6, 12, 0, 3, 97, 98, 99}
|
||||
convertor.DecodeByte(byteData, &result)
|
||||
fmt.Println(result) //"abc"
|
||||
byteData := []byte{6, 12, 0, 3, 97, 98, 99}
|
||||
|
||||
err := convertor.DecodeByte(byteData, &result)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// abc
|
||||
}
|
||||
```
|
||||
376
docs/cryptor.md
376
docs/cryptor.md
@@ -61,8 +61,6 @@ import (
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
|
||||
### <span id="AesEcbEncrypt">AesEcbEncrypt</span>
|
||||
|
||||
<p>Encrypt data with key use AES ECB algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
||||
@@ -83,16 +81,19 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := "hello world"
|
||||
data := "hello"
|
||||
key := "abcdefghijklmnop"
|
||||
encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key))
|
||||
|
||||
fmt.Println(string(encrypted))
|
||||
encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key))
|
||||
decrypted := cryptor.AesEcbDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="AesEcbDecrypt">AesEcbDecrypt</span>
|
||||
|
||||
<p>Decrypt data with key use AES ECB algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
||||
@@ -113,16 +114,19 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := "hello world"
|
||||
data := "hello"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key))
|
||||
decrypted := cryptor.AesEcbDecrypt(encrypted, []byte(key))
|
||||
fmt.Println(string(decrypted)) //hello world
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="AesCbcEncrypt">AesCbcEncrypt</span>
|
||||
|
||||
<p>Encrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
||||
@@ -143,16 +147,19 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := "hello world"
|
||||
data := "hello"
|
||||
key := "abcdefghijklmnop"
|
||||
encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
|
||||
|
||||
fmt.Println(string(encrypted))
|
||||
encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
|
||||
decrypted := cryptor.AesCbcDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="AesCbcDecrypt">AesCbcDecrypt</span>
|
||||
|
||||
<p>Decrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
||||
@@ -174,16 +181,19 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := "hello world"
|
||||
data := "hello"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
|
||||
decrypted := cryptor.AesCbcDecrypt(encrypted, []byte(key))
|
||||
fmt.Println(string(decrypted)) //hello world
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="AesCtrCrypt">AesCtrCrypt</span>
|
||||
|
||||
<p>Encrypt or decrypt data with key use AES CTR algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
||||
@@ -205,17 +215,19 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := "hello world"
|
||||
data := "hello"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
encrypted := cryptor.AesCtrCrypt([]byte(data), []byte(key))
|
||||
decrypted := cryptor.AesCtrCrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted)) //hello world
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="AesCfbEncrypt">AesCfbEncrypt</span>
|
||||
|
||||
<p>Encrypt data with key use AES CFB algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
||||
@@ -237,15 +249,19 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := "hello world"
|
||||
data := "hello"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key))
|
||||
fmt.Println(string(encrypted))
|
||||
decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="AesCfbDecrypt">AesCfbDecrypt</span>
|
||||
|
||||
<p>Decrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
||||
@@ -267,16 +283,19 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := "hello world"
|
||||
data := "hello"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key))
|
||||
decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key))
|
||||
fmt.Println(string(decrypted)) //hello world
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="AesOfbEncrypt">AesOfbEncrypt</span>
|
||||
|
||||
<p>Enecrypt data with key use AES OFB algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
||||
@@ -298,15 +317,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := "hello world"
|
||||
data := "hello"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key))
|
||||
fmt.Println(string(encrypted))
|
||||
decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="AesCfbDecrypt">AesOfbDecrypt</span>
|
||||
|
||||
<p>Decrypt data with key use AES OFB algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
||||
@@ -328,17 +350,19 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := "hello world"
|
||||
data := "hello"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key))
|
||||
decrypted := cryptor.AesOfbDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted)) //hello world
|
||||
decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Base64StdEncode">Base64StdEncode</span>
|
||||
|
||||
<p>Encode string with base64 encoding.</p>
|
||||
@@ -359,13 +383,13 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
base64Str := cryptor.Base64StdEncode("hello world")
|
||||
fmt.Println(base64Str) //aGVsbG8gd29ybGQ=
|
||||
base64Str := cryptor.Base64StdEncode("hello")
|
||||
fmt.Println(base64Str)
|
||||
|
||||
// Output:
|
||||
// aGVsbG8=
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Base64StdDecode">Base64StdDecode</span>
|
||||
|
||||
<p>Decode a base64 encoded string.</p>
|
||||
@@ -387,13 +411,14 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
str := cryptor.Base64StdDecode("aGVsbG8gd29ybGQ=")
|
||||
fmt.Println(str) //hello world
|
||||
str := cryptor.Base64StdDecode("aGVsbG8=")
|
||||
fmt.Println(str)
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="DesEcbEncrypt">DesEcbEncrypt</span>
|
||||
|
||||
<p>Encrypt data with key use DES ECB algorithm. Length of `key` param should be 8.</p>
|
||||
@@ -415,16 +440,19 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := "hello world"
|
||||
data := "hello"
|
||||
key := "abcdefgh"
|
||||
|
||||
encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key))
|
||||
|
||||
fmt.Println(string(encrypted))
|
||||
decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="DesEcbDecrypt">DesEcbDecrypt</span>
|
||||
|
||||
<p>Decrypt data with key use DES ECB algorithm. Length of `key` param should be 8.</p>
|
||||
@@ -446,17 +474,20 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := "hello world"
|
||||
data := "hello"
|
||||
key := "abcdefgh"
|
||||
encrypted := cryptor.DesEcbEncrypt([]byte(data), []byt(key)
|
||||
|
||||
encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key))
|
||||
|
||||
decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted)) //hello world
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="DesCbcEncrypt">DesCbcEncrypt</span>
|
||||
|
||||
<p>Encrypt data with key use DES CBC algorithm. Length of `key` param should be 8.</p>
|
||||
@@ -478,16 +509,19 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := "hello world"
|
||||
data := "hello"
|
||||
key := "abcdefgh"
|
||||
encrypted := cryptor.DesCbcEncrypt([]byte(data), []byt(key)
|
||||
|
||||
fmt.Println(string(encrypted))
|
||||
encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key))
|
||||
decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="DesCbcDecrypt">DesCbcDecrypt</span>
|
||||
|
||||
<p>Decrypt data with key use DES CBC algorithm. Length of `key` param should be 8.</p>
|
||||
@@ -509,17 +543,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := "hello world"
|
||||
data := "hello"
|
||||
key := "abcdefgh"
|
||||
encrypted := cryptor.DesCbcEncrypt([]byte(data), []byt(key)
|
||||
decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted)) //hello world
|
||||
|
||||
encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key))
|
||||
decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="DesCtrCrypt">DesCtrCrypt</span>
|
||||
|
||||
<p>Encrypt or decrypt data with key use DES CTR algorithm. Length of `key` param should be 8.</p>
|
||||
@@ -541,17 +576,19 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := "hello world"
|
||||
data := "hello"
|
||||
key := "abcdefgh"
|
||||
|
||||
encrypted := cryptor.DesCtrCrypt([]byte(data), []byte(key))
|
||||
decrypted := cryptor.DesCtrCrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted)) //hello world
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="DesCfbEncrypt">DesCfbEncrypt</span>
|
||||
|
||||
<p>Encrypt data with key use DES CFB algorithm. Length of `key` param should be 8.</p>
|
||||
@@ -573,15 +610,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := "hello world"
|
||||
data := "hello"
|
||||
key := "abcdefgh"
|
||||
encrypted := cryptor.DesCfbEncrypt([]byte(data), []byt(key)
|
||||
fmt.Println(string(encrypted))
|
||||
|
||||
encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key))
|
||||
decrypted := cryptor.DesCfbDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="DesCfbDecrypt">DesCfbDecrypt</span>
|
||||
|
||||
<p>Decrypt data with key use DES CBC algorithm. Length of `key` param should be 8.</p>
|
||||
@@ -603,16 +643,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := "hello world"
|
||||
data := "hello"
|
||||
key := "abcdefgh"
|
||||
encrypted := cryptor.DesCfbEncrypt([]byte(data), []byt(key)
|
||||
|
||||
encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key))
|
||||
decrypted := cryptor.DesCfbDecrypt(encrypted, []byte(key))
|
||||
fmt.Println(string(decrypted)) //hello world
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="DesOfbEncrypt">DesOfbEncrypt</span>
|
||||
|
||||
<p>Enecrypt data with key use DES OFB algorithm. Length of `key` param should be 8.</p>
|
||||
@@ -634,15 +676,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := "hello world"
|
||||
data := "hello"
|
||||
key := "abcdefgh"
|
||||
|
||||
encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key))
|
||||
fmt.Println(string(encrypted))
|
||||
decrypted := cryptor.DesOfbDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="DesOfbDecrypt">DesOfbDecrypt</span>
|
||||
|
||||
<p>Decrypt data with key use DES OFB algorithm. Length of `key` param should be 8.</p>
|
||||
@@ -664,17 +709,19 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := "hello world"
|
||||
data := "hello"
|
||||
key := "abcdefgh"
|
||||
|
||||
encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key))
|
||||
decrypted := cryptor.DesOfbDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted)) //hello world
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="HmacMd5">HmacMd5</span>
|
||||
|
||||
<p>Get the md5 hmac hash of string.</p>
|
||||
@@ -696,13 +743,16 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
s := cryptor.HmacMd5("hello world", "12345"))
|
||||
fmt.Println(s) //5f4c9faaff0a1ad3007d9ddc06abe36d
|
||||
str := "hello"
|
||||
key := "12345"
|
||||
|
||||
hms := cryptor.HmacMd5(str, key)
|
||||
fmt.Println(hms)
|
||||
|
||||
// Output:
|
||||
// e834306eab892d872525d4918a7a639a
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="HmacSha1">HmacSha1</span>
|
||||
|
||||
<p>Get the sha1 hmac hash of string.</p>
|
||||
@@ -724,13 +774,16 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
s := cryptor.HmacSha1("hello world", "12345"))
|
||||
fmt.Println(s) //3826f812255d8683f051ee97346d1359234d5dbd
|
||||
str := "hello"
|
||||
key := "12345"
|
||||
|
||||
hms := cryptor.HmacSha1(str, key)
|
||||
fmt.Println(hms)
|
||||
|
||||
// Output:
|
||||
// 5c6a9db0cccb92e36ed0323fd09b7f936de9ace0
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="HmacSha256">HmacSha256</span>
|
||||
|
||||
<p>Get the sha256 hmac hash of string</p>
|
||||
@@ -752,13 +805,17 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
s := cryptor.HmacSha256("hello world", "12345"))
|
||||
fmt.Println(s) //9dce2609f2d67d41f74c7f9efc8ccd44370d41ad2de52982627588dfe7289ab8
|
||||
str := "hello"
|
||||
key := "12345"
|
||||
|
||||
hms := cryptor.HmacSha256(str, key)
|
||||
fmt.Println(hms)
|
||||
|
||||
// Output:
|
||||
// 315bb93c4e989862ba09cb62e05d73a5f376cb36f0d786edab0c320d059fde75
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="HmacSha512">HmacSha512</span>
|
||||
|
||||
<p>Get the sha512 hmac hash of string.</p>
|
||||
@@ -780,14 +837,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
s := cryptor.HmacSha512("hello world", "12345"))
|
||||
fmt.Println(s)
|
||||
//5b1563ac4e9b49c9ada8ccb232588fc4f0c30fd12f756b3a0b95af4985c236ca60925253bae10ce2c6bf9af1c1679b51e5395ff3d2826c0a2c7c0d72225d4175
|
||||
str := "hello"
|
||||
key := "12345"
|
||||
|
||||
hms := cryptor.HmacSha512(str, key)
|
||||
fmt.Println(hms)
|
||||
|
||||
// Output:
|
||||
// dd8f1290a9dd23d354e2526d9a2e9ce8cffffdd37cb320800d1c6c13d2efc363288376a196c5458daf53f8e1aa6b45a6d856303d5c0a2064bff9785861d48cfc
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Md5String">Md5String</span>
|
||||
|
||||
<p>Get the md5 value of string.</p>
|
||||
@@ -809,13 +870,16 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
s := cryptor.Md5String("hello"))
|
||||
fmt.Println(s) //5d41402abc4b2a76b9719d911017c592
|
||||
str := "hello"
|
||||
|
||||
md5Str := cryptor.Md5String(str)
|
||||
fmt.Println(md5Str)
|
||||
|
||||
// Output:
|
||||
// 5d41402abc4b2a76b9719d911017c592
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Md5File">Md5File</span>
|
||||
|
||||
<p>Get the md5 value of file.</p>
|
||||
@@ -842,8 +906,6 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Sha1">Sha1</span>
|
||||
|
||||
<p>Get the sha1 value of string.</p>
|
||||
@@ -865,13 +927,16 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
s := cryptor.Sha1("hello world"))
|
||||
fmt.Println(s) //2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
|
||||
str := "hello"
|
||||
|
||||
result := cryptor.Sha1(str)
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Sha256">Sha256</span>
|
||||
|
||||
<p>Get the sha256 value of string.</p>
|
||||
@@ -893,13 +958,16 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
s := cryptor.Sha256("hello world"))
|
||||
fmt.Println(s) //b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
|
||||
str := "hello"
|
||||
|
||||
result := cryptor.Sha256(str)
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Sha512">Sha512</span>
|
||||
|
||||
<p>Get the sha512 value of string.</p>
|
||||
@@ -921,13 +989,16 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
s := cryptor.Sha512("hello world"))
|
||||
fmt.Println(s) //309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f
|
||||
str := "hello"
|
||||
|
||||
result := cryptor.Sha512(str)
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="GenerateRsaKey">GenerateRsaKey</span>
|
||||
|
||||
<p>Create the rsa public and private key file in current directory.</p>
|
||||
@@ -956,8 +1027,6 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="RsaEncrypt">RsaEncrypt</span>
|
||||
|
||||
<p>Encrypt data with public key file useing ras algorithm.</p>
|
||||
@@ -981,19 +1050,21 @@ import (
|
||||
func main() {
|
||||
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
data := []byte("hello world")
|
||||
|
||||
data := []byte("hello")
|
||||
encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
|
||||
decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
|
||||
|
||||
fmt.Println(string(decrypted)) //hello world
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="RsaDecrypt">RsaDecrypt</span>
|
||||
|
||||
<p>Decrypt data with private key file useing ras algorithm.</p>
|
||||
@@ -1017,14 +1088,17 @@ import (
|
||||
func main() {
|
||||
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
data := []byte("hello world")
|
||||
|
||||
data := []byte("hello")
|
||||
encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
|
||||
decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
|
||||
|
||||
fmt.Println(string(decrypted)) //hello world
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -46,7 +46,7 @@ import (
|
||||
func NewHashMap() *HashMap
|
||||
```
|
||||
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -72,7 +72,7 @@ func main() {
|
||||
func NewHashMapWithCapacity(size, capacity uint64) *HashMap
|
||||
```
|
||||
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -98,7 +98,7 @@ func main() {
|
||||
func (hm *HashMap) Get(key any) any
|
||||
```
|
||||
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -126,7 +126,7 @@ func main() {
|
||||
func (hm *HashMap) Put(key any, value any) any
|
||||
```
|
||||
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -155,7 +155,7 @@ func main() {
|
||||
func (hm *HashMap) Delete(key any)
|
||||
```
|
||||
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -187,7 +187,7 @@ func main() {
|
||||
func (hm *HashMap) Contains(key any) bool
|
||||
```
|
||||
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -217,7 +217,7 @@ func main() {
|
||||
func (hm *HashMap) Iterate(iteratee func(key, value any))
|
||||
```
|
||||
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -252,7 +252,7 @@ func main() {
|
||||
func (hm *HashMap) Keys() []any
|
||||
```
|
||||
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -284,7 +284,7 @@ func main() {
|
||||
func (hm *HashMap) Values() []any
|
||||
```
|
||||
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
@@ -48,7 +48,7 @@ type MaxHeap[T any] struct {
|
||||
}
|
||||
func NewMaxHeap[T any](comparator lancetconstraints.Comparator) *MaxHeap[T]
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -89,7 +89,7 @@ func main() {
|
||||
```go
|
||||
func (h *MaxHeap[T]) Push(value T)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -136,7 +136,7 @@ func main() {
|
||||
```go
|
||||
func (h *MaxHeap[T]) Pop() (T, bool)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -184,7 +184,7 @@ func main() {
|
||||
```go
|
||||
func (h *MaxHeap[T]) Peek() (T, bool)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -232,7 +232,7 @@ func main() {
|
||||
```go
|
||||
func (h *MaxHeap[T]) Data() []T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -277,7 +277,7 @@ func main() {
|
||||
```go
|
||||
func (h *MaxHeap[T]) Size() int
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -323,7 +323,7 @@ func main() {
|
||||
```go
|
||||
func (h *MaxHeap[T]) PrintStructure()
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
@@ -81,7 +81,7 @@ type SinglyLink[T any] struct {
|
||||
}
|
||||
func NewSinglyLink[T any]() *SinglyLink[T]
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -107,7 +107,7 @@ func main() {
|
||||
```go
|
||||
func (link *SinglyLink[T]) Values() []T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -139,7 +139,7 @@ func main() {
|
||||
```go
|
||||
func (link *SinglyLink[T]) InsertAt(index int, value T)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -174,7 +174,7 @@ func main() {
|
||||
```go
|
||||
func (link *SinglyLink[T]) InsertAtHead(value T)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -206,7 +206,7 @@ func main() {
|
||||
```go
|
||||
func (link *SinglyLink[T]) InsertAtTail(value T)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -237,7 +237,7 @@ func main() {
|
||||
```go
|
||||
func (link *SinglyLink[T]) DeleteAt(index int)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -271,7 +271,7 @@ func main() {
|
||||
```go
|
||||
func (link *SinglyLink[T]) DeleteAtHead()
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -306,7 +306,7 @@ func main() {
|
||||
```go
|
||||
func (link *SinglyLink[T]) DeleteAtTail()
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -339,7 +339,7 @@ func main() {
|
||||
```go
|
||||
func (link *SinglyLink[T]) DeleteValue(value T)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -373,7 +373,7 @@ func main() {
|
||||
```go
|
||||
func (link *SinglyLink[T]) Reverse()
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -405,7 +405,7 @@ func main() {
|
||||
```go
|
||||
func (link *SinglyLink[T]) GetMiddleNode() *datastructure.LinkNode[T]
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -437,7 +437,7 @@ func main() {
|
||||
```go
|
||||
func (link *SinglyLink[T]) Size() int
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -468,7 +468,7 @@ func main() {
|
||||
```go
|
||||
func (link *SinglyLink[T]) IsEmpty() bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -500,7 +500,7 @@ func main() {
|
||||
```go
|
||||
func (link *SinglyLink[T]) Clear()
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -533,7 +533,7 @@ func main() {
|
||||
```go
|
||||
func (link *SinglyLink[T]) Clear()
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -576,7 +576,7 @@ type DoublyLink[T any] struct {
|
||||
}
|
||||
func NewDoublyLink[T any]() *DoublyLink[T]
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -602,7 +602,7 @@ func main() {
|
||||
```go
|
||||
func (link *DoublyLink[T]) Values() []T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -634,7 +634,7 @@ func main() {
|
||||
```go
|
||||
func (link *DoublyLink[T]) InsertAt(index int, value T)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -669,7 +669,7 @@ func main() {
|
||||
```go
|
||||
func (link *DoublyLink[T]) InsertAtHead(value T)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -701,7 +701,7 @@ func main() {
|
||||
```go
|
||||
func (link *DoublyLink[T]) InsertAtTail(value T)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -732,7 +732,7 @@ func main() {
|
||||
```go
|
||||
func (link *DoublyLink[T]) DeleteAt(index int)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -766,7 +766,7 @@ func main() {
|
||||
```go
|
||||
func (link *DoublyLink[T]) DeleteAtHead()
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -801,7 +801,7 @@ func main() {
|
||||
```go
|
||||
func (link *DoublyLink[T]) DeleteAtTail()
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -835,7 +835,7 @@ func main() {
|
||||
```go
|
||||
func (link *DoublyLink[T]) Reverse()
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -867,7 +867,7 @@ func main() {
|
||||
```go
|
||||
func (link *DoublyLink[T]) GetMiddleNode() *datastructure.LinkNode[T]
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -899,7 +899,7 @@ func main() {
|
||||
```go
|
||||
func (link *DoublyLink[T]) Size() int
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -930,7 +930,7 @@ func main() {
|
||||
```go
|
||||
func (link *DoublyLink[T]) IsEmpty() bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -962,7 +962,7 @@ func main() {
|
||||
```go
|
||||
func (link *DoublyLink[T]) Clear()
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -995,7 +995,7 @@ func main() {
|
||||
```go
|
||||
func (link *DoublyLink[T]) Clear()
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
@@ -47,6 +47,13 @@ import (
|
||||
- [Unique](#Unique)
|
||||
- [Union](#Union)
|
||||
- [Intersection](#Intersection)
|
||||
- [Difference](#Difference)
|
||||
- [SymmetricDifference](#SymmetricDifference)
|
||||
- [RetainAll](#RetainAll)
|
||||
- [DeleteAll](#DeleteAll)
|
||||
- [ForEach](#ForEach)
|
||||
- [Iterator](#Iterator)
|
||||
- [ListToMap](#ListToMap)
|
||||
- [SubList](#SubList)
|
||||
- [DeleteIf](#DeleteIf)
|
||||
|
||||
@@ -62,7 +69,7 @@ NewList function return a list pointer</p>
|
||||
|
||||
```go
|
||||
type List[T any] struct {
|
||||
data []T
|
||||
data []T
|
||||
}
|
||||
func NewList[T any](data []T) *List[T]
|
||||
```
|
||||
@@ -671,8 +678,8 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := make([]int, 0, 100)
|
||||
|
||||
data := make([]int, 0, 100)
|
||||
|
||||
li := list.NewList(data)
|
||||
|
||||
fmt.Println(li.Cap()) // 100
|
||||
@@ -828,6 +835,233 @@ func main() {
|
||||
|
||||
|
||||
|
||||
### <span id="Difference">Difference</span>
|
||||
<p>Return a list whose element in the original list, not in the given list.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) Difference(other *List[T]) *List[T]
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
list1 := NewList([]int{1, 2, 3})
|
||||
list2 := NewList([]int{1, 2, 4})
|
||||
|
||||
list3 := list1.Intersection(list2)
|
||||
|
||||
fmt.Println(list3.Data()) //3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="SymmetricDifference">SymmetricDifference</span>
|
||||
<p>Oppoiste operation of intersection function.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) SymmetricDifference(other *List[T]) *List[T]
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
list1 := NewList([]int{1, 2, 3})
|
||||
list2 := NewList([]int{1, 2, 4})
|
||||
|
||||
list3 := list1.Intersection(list2)
|
||||
|
||||
fmt.Println(list3.Data()) //3, 4
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="RetainAll">RetainAll</span>
|
||||
<p>Retains only the elements in this list that are contained in the given list.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) RetainAll(list *List[T]) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
list := NewList([]int{1, 2, 3, 4})
|
||||
list1 := NewList([]int{1, 2, 3, 4})
|
||||
list2 := NewList([]int{1, 2, 3, 4})
|
||||
|
||||
retain := NewList([]int{1, 2})
|
||||
retain1 := NewList([]int{2, 3})
|
||||
retain2 := NewList([]int{1, 2, 5})
|
||||
|
||||
list.RetainAll(retain)
|
||||
list1.RetainAll(retain1)
|
||||
list2.RetainAll(retain2)
|
||||
|
||||
fmt.Println(list.Data()) //1, 2
|
||||
fmt.Println(list1.Data()) //2, 3
|
||||
fmt.Println(list2.Data()) //1, 2
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="DeleteAll">DeleteAll</span>
|
||||
<p>Removes from this list all of its elements that are contained in the given list.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) DeleteAll(list *List[T]) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
list := NewList([]int{1, 2, 3, 4})
|
||||
list1 := NewList([]int{1, 2, 3, 4})
|
||||
list2 := NewList([]int{1, 2, 3, 4})
|
||||
|
||||
del := NewList([]int{1})
|
||||
del1 := NewList([]int{2, 3})
|
||||
del2 := NewList([]int{1, 2, 5})
|
||||
|
||||
list.DeleteAll(del)
|
||||
list1.DeleteAll(del1)
|
||||
list2.DeleteAll(del2)
|
||||
|
||||
fmt.Println(list.Data()) //2,3,4
|
||||
fmt.Println(list1.Data()) //1,4
|
||||
fmt.Println(list2.Data()) //3,4
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="ForEach">ForEach</span>
|
||||
<p>Performs the given action for each element of the list.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) ForEach(consumer func(T))
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
list := NewList([]int{1, 2, 3, 4})
|
||||
|
||||
result := make([]int, 0)
|
||||
list.ForEach(func(i int) {
|
||||
result = append(result, i)
|
||||
})
|
||||
|
||||
fmt.Println(result.Data()) //1,2,3,4
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="Iterator">Iterator</span>
|
||||
<p>Returns an iterator over the elements in this list in proper sequence.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) Iterator() iterator.Iterator[T]
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
list := NewList([]int{1, 2, 3, 4})
|
||||
|
||||
iterator := list.Iterator()
|
||||
|
||||
result := make([]int, 0)
|
||||
for iterator.HasNext() {
|
||||
item, _ := iterator.Next()
|
||||
result = append(result, item)
|
||||
}
|
||||
|
||||
fmt.Println(result.Data()) //1,2,3,4
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="ListToMap">ListToMap</span>
|
||||
<p>Converts a list to a map based on iteratee function.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ListToMap[T any, K comparable, V any](list *List[T], iteratee func(T) (K, V)) map[K]V
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
list := NewList([]int{1, 2, 3, 4})
|
||||
|
||||
result := ListToMap(list, func(n int) (int, bool) {
|
||||
return n, n > 1
|
||||
})
|
||||
|
||||
fmt.Println(result) //map[int]bool{1: false, 2: true, 3: true, 4: true}
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="SubList">SubList</span>
|
||||
<p>SubList returns a sub list of the original list between the specified fromIndex, inclusive, and toIndex, exclusive.</p>
|
||||
@@ -876,9 +1110,9 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
l := list.NewList([]int{1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1})
|
||||
l := list.NewList([]int{1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1})
|
||||
|
||||
fmt.Println(l.DeleteIf(func(a int) bool { return a == 1 })) // 12
|
||||
fmt.Println(l.Data()) // []int{2, 3, 4}
|
||||
fmt.Println(l.DeleteIf(func(a int) bool { return a == 1 })) // 12
|
||||
fmt.Println(l.Data()) // []int{2, 3, 4}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -34,7 +34,6 @@ import (
|
||||
- [PopLast](#PopLast)
|
||||
- [DeleteAt](#DeleteAt)
|
||||
- [InsertAt](#InsertAt)
|
||||
|
||||
- [UpdateAt](#UpdateAt)
|
||||
- [Equal](#Equal)
|
||||
- [IsEmpty](#IsEmpty)
|
||||
@@ -48,6 +47,13 @@ import (
|
||||
- [Unique](#Unique)
|
||||
- [Union](#Union)
|
||||
- [Intersection](#Intersection)
|
||||
- [Difference](#Difference)
|
||||
- [SymmetricDifference](#SymmetricDifference)
|
||||
- [RetainAll](#RetainAll)
|
||||
- [DeleteAll](#DeleteAll)
|
||||
- [ForEach](#ForEach)
|
||||
- [Iterator](#Iterator)
|
||||
- [ListToMap](#ListToMap)
|
||||
- [SubList](#SubList)
|
||||
- [DeleteIf](#DeleteIf)
|
||||
|
||||
@@ -62,11 +68,11 @@ import (
|
||||
|
||||
```go
|
||||
type List[T any] struct {
|
||||
data []T
|
||||
data []T
|
||||
}
|
||||
func NewList[T any](data []T) *List[T]
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -92,7 +98,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) Contain(value T) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -121,7 +127,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) Data() []T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -150,7 +156,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) ValueOf(index int) (*T, bool)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -180,7 +186,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) IndexOf(value T) int
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -207,7 +213,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) LastIndexOf(value T) int
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -233,7 +239,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) IndexOfFunc(f func(T) bool) int
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -259,7 +265,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) LastIndexOfFunc(f func(T) bool) int
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -287,7 +293,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) Push(value T)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -316,7 +322,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) PopFirst() (*T, bool)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -348,7 +354,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) PopLast() (*T, bool)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -379,7 +385,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) DeleteAt(index int)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -417,7 +423,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) InsertAt(index int, value T)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -454,7 +460,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) UpdateAt(index int, value T)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -487,7 +493,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) Equal(other *List[T]) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -517,7 +523,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) IsEmpty() bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -547,7 +553,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) Clear()
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -575,7 +581,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) Clone() *List[T]
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -604,7 +610,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) Merge(other *List[T]) *List[T]
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -633,7 +639,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) Size() int
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -660,7 +666,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) Cap() int
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -671,8 +677,8 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := make([]int, 0, 100)
|
||||
|
||||
data := make([]int, 0, 100)
|
||||
|
||||
li := list.NewList(data)
|
||||
|
||||
fmt.Println(li.Cap()) // 100
|
||||
@@ -689,7 +695,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) Swap(i, j int)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -718,7 +724,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) Reverse()
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -747,7 +753,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) Unique()
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -776,7 +782,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) Union(other *List[T]) *List[T]
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -806,7 +812,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) Intersection(other *List[T]) *List[T]
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -826,16 +832,244 @@ func main() {
|
||||
```
|
||||
|
||||
|
||||
### <span id="Difference">Difference</span>
|
||||
<p>差集运算。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) Difference(other *List[T]) *List[T]
|
||||
```
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
list1 := NewList([]int{1, 2, 3})
|
||||
list2 := NewList([]int{1, 2, 4})
|
||||
|
||||
list3 := list1.Intersection(list2)
|
||||
|
||||
fmt.Println(list3.Data()) //3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="SymmetricDifference">SymmetricDifference</span>
|
||||
<p>对称差集运算。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) SymmetricDifference(other *List[T]) *List[T]
|
||||
```
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
list1 := NewList([]int{1, 2, 3})
|
||||
list2 := NewList([]int{1, 2, 4})
|
||||
|
||||
list3 := list1.Intersection(list2)
|
||||
|
||||
fmt.Println(list3.Data()) //3, 4
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="RetainAll">RetainAll</span>
|
||||
<p>仅保留列表中包含在给定列表中的元素。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) RetainAll(list *List[T]) bool
|
||||
```
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
list := NewList([]int{1, 2, 3, 4})
|
||||
list1 := NewList([]int{1, 2, 3, 4})
|
||||
list2 := NewList([]int{1, 2, 3, 4})
|
||||
|
||||
retain := NewList([]int{1, 2})
|
||||
retain1 := NewList([]int{2, 3})
|
||||
retain2 := NewList([]int{1, 2, 5})
|
||||
|
||||
list.RetainAll(retain)
|
||||
list1.RetainAll(retain1)
|
||||
list2.RetainAll(retain2)
|
||||
|
||||
fmt.Println(list.Data()) //1, 2
|
||||
fmt.Println(list1.Data()) //2, 3
|
||||
fmt.Println(list2.Data()) //1, 2
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="DeleteAll">DeleteAll</span>
|
||||
<p>从列表中删除给定列表中包含的所有元素。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) DeleteAll(list *List[T]) bool
|
||||
```
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
list := NewList([]int{1, 2, 3, 4})
|
||||
list1 := NewList([]int{1, 2, 3, 4})
|
||||
list2 := NewList([]int{1, 2, 3, 4})
|
||||
|
||||
del := NewList([]int{1})
|
||||
del1 := NewList([]int{2, 3})
|
||||
del2 := NewList([]int{1, 2, 5})
|
||||
|
||||
list.DeleteAll(del)
|
||||
list1.DeleteAll(del1)
|
||||
list2.DeleteAll(del2)
|
||||
|
||||
fmt.Println(list.Data()) //2,3,4
|
||||
fmt.Println(list1.Data()) //1,4
|
||||
fmt.Println(list2.Data()) //3,4
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="ForEach">ForEach</span>
|
||||
<p>对列表的每个元素执行给定的操作。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) ForEach(consumer func(T))
|
||||
```
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
list := NewList([]int{1, 2, 3, 4})
|
||||
|
||||
result := make([]int, 0)
|
||||
list.ForEach(func(i int) {
|
||||
result = append(result, i)
|
||||
})
|
||||
|
||||
fmt.Println(result.Data()) //1,2,3,4
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="Iterator">Iterator</span>
|
||||
<p>按顺序返回列表中元素的迭代器。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) Iterator() iterator.Iterator[T]
|
||||
```
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
list := NewList([]int{1, 2, 3, 4})
|
||||
|
||||
iterator := list.Iterator()
|
||||
|
||||
result := make([]int, 0)
|
||||
for iterator.HasNext() {
|
||||
item, _ := iterator.Next()
|
||||
result = append(result, item)
|
||||
}
|
||||
|
||||
fmt.Println(result.Data()) //1,2,3,4
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="ListToMap">ListToMap</span>
|
||||
<p>基于iteratee函数将列表转换为映射map。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ListToMap[T any, K comparable, V any](list *List[T], iteratee func(T) (K, V)) map[K]V
|
||||
```
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
list := NewList([]int{1, 2, 3, 4})
|
||||
|
||||
result := ListToMap(list, func(n int) (int, bool) {
|
||||
return n, n > 1
|
||||
})
|
||||
|
||||
fmt.Println(result) //map[int]bool{1: false, 2: true, 3: true, 4: true}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="SubList">SubList</span>
|
||||
<p>SubList returns a sub list of the original list between the specified fromIndex, inclusive, and toIndex, exclusive.</p>
|
||||
<p>返回指定的fromIndex(包含)和toIndex(不包含)之间的原始列表的子列表。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) SubList(fromIndex, toIndex int) *List[T]
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -863,7 +1097,7 @@ func main() {
|
||||
```go
|
||||
func (l *List[T]) DeleteIf(f func(T) bool) int
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -874,9 +1108,9 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
l := list.NewList([]int{1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1})
|
||||
l := list.NewList([]int{1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1})
|
||||
|
||||
fmt.Println(l.DeleteIf(func(a int) bool { return a == 1 })) // 12
|
||||
fmt.Println(l.Data()) // []int{2, 3, 4}
|
||||
fmt.Println(l.DeleteIf(func(a int) bool { return a == 1 })) // 12
|
||||
fmt.Println(l.Data()) // []int{2, 3, 4}
|
||||
}
|
||||
```
|
||||
@@ -99,7 +99,7 @@ type ArrayQueue[T any] struct {
|
||||
size int
|
||||
}
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -125,7 +125,7 @@ func main() {
|
||||
```go
|
||||
func (q *ArrayQueue[T]) Data() []T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -152,7 +152,7 @@ func main() {
|
||||
```go
|
||||
func (q *ArrayQueue[T]) Enqueue(item T) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -183,7 +183,7 @@ func main() {
|
||||
```go
|
||||
func (q *ArrayQueue[T]) Dequeue() (T, bool)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -215,7 +215,7 @@ func main() {
|
||||
```go
|
||||
func (q *ArrayQueue[T]) Front() T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -247,7 +247,7 @@ func main() {
|
||||
```go
|
||||
func (q *ArrayQueue[T]) Back() T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -278,7 +278,7 @@ func main() {
|
||||
```go
|
||||
func (q *ArrayQueue[T]) Size() int
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -308,7 +308,7 @@ func main() {
|
||||
```go
|
||||
func (q *ArrayQueue[T]) IsEmpty() bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -341,7 +341,7 @@ func main() {
|
||||
```go
|
||||
func (q *ArrayQueue[T]) IsFull() bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -373,7 +373,7 @@ func main() {
|
||||
```go
|
||||
func (q *ArrayQueue[T]) Clear()
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -404,7 +404,7 @@ func main() {
|
||||
```go
|
||||
func (q *ArrayQueue[T]) Contain(value T) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -448,7 +448,7 @@ type QueueNode[T any] struct {
|
||||
Next *QueueNode[T]
|
||||
}
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -474,7 +474,7 @@ func main() {
|
||||
```go
|
||||
func (q *LinkedQueue[T]) Data() []T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -501,7 +501,7 @@ func main() {
|
||||
```go
|
||||
func (q *LinkedQueue[T]) Enqueue(value T)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -532,7 +532,7 @@ func main() {
|
||||
```go
|
||||
func (q *LinkedQueue[T]) Dequeue() (T, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -564,7 +564,7 @@ func main() {
|
||||
```go
|
||||
func (q *LinkedQueue[T]) Front() (*T, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -596,7 +596,7 @@ func main() {
|
||||
```go
|
||||
func (q *LinkedQueue[T]) Back() (*T, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -627,7 +627,7 @@ func main() {
|
||||
```go
|
||||
func (q *LinkedQueue[T]) Size() int
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -657,7 +657,7 @@ func main() {
|
||||
```go
|
||||
func (q *LinkedQueue[T]) IsEmpty() bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -690,7 +690,7 @@ func main() {
|
||||
```go
|
||||
func (q *LinkedQueue[T]) Clear()
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -721,7 +721,7 @@ func main() {
|
||||
```go
|
||||
func (q *LinkedQueue[T]) Contain(value T) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -763,7 +763,7 @@ type CircularQueue[T any] struct {
|
||||
capacity int
|
||||
}
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -789,7 +789,7 @@ func main() {
|
||||
```go
|
||||
func (q *CircularQueue[T]) Data() []T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -816,7 +816,7 @@ func main() {
|
||||
```go
|
||||
func (q *CircularQueue[T]) Enqueue(value T) error
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -847,7 +847,7 @@ func main() {
|
||||
```go
|
||||
func (q *CircularQueue[T]) Dequeue() (*T, bool)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -880,7 +880,7 @@ func main() {
|
||||
```go
|
||||
func (q *CircularQueue[T]) Front() T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -912,7 +912,7 @@ func main() {
|
||||
```go
|
||||
func (q *CircularQueue[T]) Back() T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -943,7 +943,7 @@ func main() {
|
||||
```go
|
||||
func (q *CircularQueue[T]) Size() int
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -973,7 +973,7 @@ func main() {
|
||||
```go
|
||||
func (q *CircularQueue[T]) IsEmpty() bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -1006,7 +1006,7 @@ func main() {
|
||||
```go
|
||||
func (q *CircularQueue[T]) IsFull() bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -1038,7 +1038,7 @@ func main() {
|
||||
```go
|
||||
func (q *CircularQueue[T]) Clear()
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -1069,7 +1069,7 @@ func main() {
|
||||
```go
|
||||
func (q *CircularQueue[T]) Contain(value T) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -1108,7 +1108,7 @@ type PriorityQueue[T any] struct {
|
||||
comparator lancetconstraints.Comparator
|
||||
}
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -1134,7 +1134,7 @@ func main() {
|
||||
```go
|
||||
func (q *PriorityQueue[T]) Data() []T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -1161,7 +1161,7 @@ func main() {
|
||||
```go
|
||||
func (q *PriorityQueue[T]) Enqueue(item T) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -1207,7 +1207,7 @@ func main() {
|
||||
```go
|
||||
func (q *PriorityQueue[T]) Dequeue() (T, bool)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -1254,7 +1254,7 @@ func main() {
|
||||
```go
|
||||
func (q *PriorityQueue[T]) IsEmpty() bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -1301,7 +1301,7 @@ func main() {
|
||||
```go
|
||||
func (q *PriorityQueue[T]) IsFull() bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -1348,7 +1348,7 @@ func main() {
|
||||
```go
|
||||
func (q *PriorityQueue[T]) Size() int
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
@@ -55,7 +55,7 @@ import (
|
||||
type Set[T comparable] map[T]bool
|
||||
func NewSet[T comparable](items ...T) Set[T]
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -81,7 +81,7 @@ func main() {
|
||||
```go
|
||||
func NewSetFromSlice[T comparable](items []T) Set[T]
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -107,7 +107,7 @@ func main() {
|
||||
```go
|
||||
func (s Set[T]) Values() []T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -134,7 +134,7 @@ func main() {
|
||||
```go
|
||||
func (s Set[T]) Add(items ...T)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -161,7 +161,7 @@ func main() {
|
||||
```go
|
||||
func (s Set[T]) AddIfNotExist(item T) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -193,7 +193,7 @@ func main() {
|
||||
```go
|
||||
func (s Set[T]) AddIfNotExistBy(item T, checker func(element T) bool) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -232,7 +232,7 @@ func main() {
|
||||
```go
|
||||
func (s Set[T]) Delete(items ...T)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -261,7 +261,7 @@ func main() {
|
||||
```go
|
||||
func (s Set[T]) Contain(item T) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -291,7 +291,7 @@ func main() {
|
||||
```go
|
||||
func (s Set[T]) ContainAll(other Set[T]) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -321,7 +321,7 @@ func main() {
|
||||
```go
|
||||
func (s Set[T]) Size() int
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -348,7 +348,7 @@ func main() {
|
||||
```go
|
||||
func (s Set[T]) Clone() Set[T]
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -378,7 +378,7 @@ func main() {
|
||||
```go
|
||||
func (s Set[T]) Equal(other Set[T]) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -408,7 +408,7 @@ func main() {
|
||||
```go
|
||||
func (s Set[T]) Iterate(fn func(item T))
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -439,7 +439,7 @@ func main() {
|
||||
```go
|
||||
func (s Set[T]) IsEmpty() bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -468,7 +468,7 @@ func main() {
|
||||
```go
|
||||
func (s Set[T]) Union(other Set[T]) Set[T]
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -497,7 +497,7 @@ func main() {
|
||||
```go
|
||||
func (s Set[T]) Intersection(other Set[T]) Set[T]
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -525,7 +525,7 @@ func main() {
|
||||
```go
|
||||
func (s Set[T]) SymmetricDifference(other Set[T]) Set[T]
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -556,7 +556,7 @@ func main() {
|
||||
```go
|
||||
func (s Set[T]) Minus(comparedSet Set[T]) Set[T]
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
@@ -64,7 +64,7 @@ type ArrayStack[T any] struct {
|
||||
}
|
||||
func NewArrayStack[T any]() *ArrayStack[T]
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -91,7 +91,7 @@ func main() {
|
||||
```go
|
||||
func (s *ArrayStack[T]) Push(value T)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -122,7 +122,7 @@ func main() {
|
||||
```go
|
||||
func (s *ArrayStack[T]) Pop() (*T, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -157,7 +157,7 @@ func main() {
|
||||
```go
|
||||
func (s *ArrayStack[T]) Peak() (*T, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -192,7 +192,7 @@ func main() {
|
||||
```go
|
||||
func (s *ArrayStack[T]) Data() []T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -223,7 +223,7 @@ func main() {
|
||||
```go
|
||||
func (s *ArrayStack[T]) Size() int
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -254,7 +254,7 @@ func main() {
|
||||
```go
|
||||
func (s *ArrayStack[T]) IsEmpty() bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -287,7 +287,7 @@ func main() {
|
||||
```go
|
||||
func (s *ArrayStack[T]) Clear()
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -331,7 +331,7 @@ type LinkedStack[T any] struct {
|
||||
}
|
||||
func NewLinkedStack[T any]() *LinkedStack[T]
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -358,7 +358,7 @@ func main() {
|
||||
```go
|
||||
func (s *LinkedStack[T]) Push(value T)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -389,7 +389,7 @@ func main() {
|
||||
```go
|
||||
func (s *LinkedStack[T]) Pop() (*T, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -424,7 +424,7 @@ func main() {
|
||||
```go
|
||||
func (s *LinkedStack[T]) Peak() (*T, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -459,7 +459,7 @@ func main() {
|
||||
```go
|
||||
func (s *LinkedStack[T]) Data() []T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -490,7 +490,7 @@ func main() {
|
||||
```go
|
||||
func (s *LinkedStack[T]) Size() int
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -521,7 +521,7 @@ func main() {
|
||||
```go
|
||||
func (s *LinkedStack[T]) IsEmpty() bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -554,7 +554,7 @@ func main() {
|
||||
```go
|
||||
func (s *LinkedStack[T]) Clear()
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -588,7 +588,7 @@ func main() {
|
||||
```go
|
||||
func (s *LinkedStack[T]) Print()
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
@@ -62,7 +62,7 @@ type TreeNode[T any] struct {
|
||||
Right *TreeNode[T]
|
||||
}
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -103,7 +103,7 @@ func main() {
|
||||
```go
|
||||
func (t *BSTree[T]) Insert(data T)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -149,7 +149,7 @@ func main() {
|
||||
```go
|
||||
func (t *BSTree[T]) Delete(data T)
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -197,7 +197,7 @@ func main() {
|
||||
```go
|
||||
func (t *BSTree[T]) PreOrderTraverse() []T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -243,7 +243,7 @@ func main() {
|
||||
```go
|
||||
func (t *BSTree[T]) InOrderTraverse() []T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -289,7 +289,7 @@ func main() {
|
||||
```go
|
||||
func (t *BSTree[T]) PostOrderTraverse() []T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -335,7 +335,7 @@ func main() {
|
||||
```go
|
||||
func (t *BSTree[T]) LevelOrderTraverse() []T
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -381,7 +381,7 @@ func main() {
|
||||
```go
|
||||
func (t *BSTree[T]) Depth() int
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -427,7 +427,7 @@ func main() {
|
||||
```go
|
||||
func (t *BSTree[T]) HasSubTree(subTree *BSTree[T]) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -479,7 +479,7 @@ func main() {
|
||||
```go
|
||||
func (t *BSTree[T]) Print()
|
||||
```
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
470
docs/datetime.md
470
docs/datetime.md
@@ -1,16 +1,18 @@
|
||||
# Datetime
|
||||
|
||||
Package datetime supports date and time format and compare.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/datetime/datetime.go](https://github.com/duke-git/lancet/blob/main/datetime/datetime.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/datetime/conversion.go](https://github.com/duke-git/lancet/blob/main/datetime/conversion.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/datetime/datetime.go](https://github.com/duke-git/lancet/blob/main/datetime/datetime.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/datetime/conversion.go](https://github.com/duke-git/lancet/blob/main/datetime/conversion.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Usage:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
@@ -20,66 +22,67 @@ import (
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [AddDay](#AddDay)
|
||||
- [AddHour](#AddHour)
|
||||
- [AddMinute](#AddMinute)
|
||||
- [BeginOfMinute](#BeginOfMinute)
|
||||
- [BeginOfHour](#BeginOfHour)
|
||||
- [BeginOfDay](#BeginOfDay)
|
||||
- [BeginOfWeek](#BeginOfWeek)
|
||||
- [BeginOfMonth](#BeginOfMonth)
|
||||
- [BeginOfYear](#BeginOfYear)
|
||||
- [EndOfMinute](#EndOfMinute)
|
||||
- [EndOfHour](#EndOfHour)
|
||||
- [EndOfDay](#EndOfDay)
|
||||
- [EndOfWeek](#EndOfWeek)
|
||||
- [EndOfMonth](#EndOfMonth)
|
||||
- [EndOfYear](#EndOfYear)
|
||||
- [GetNowDate](#GetNowDate)
|
||||
- [GetNowTime](#GetNowTime)
|
||||
- [GetNowDateTime](#GetNowDateTime)
|
||||
- [GetZeroHourTimestamp](#GetZeroHourTimestamp)
|
||||
- [GetNightTimestamp](#GetNightTimestamp)
|
||||
- [FormatTimeToStr](#FormatTimeToStr)
|
||||
- [FormatStrToTime](#FormatStrToTime)
|
||||
- [NewUnixNow](#NewUnixNow)
|
||||
- [NewUnix](#NewUnix)
|
||||
- [NewFormat](#NewFormat)
|
||||
- [NewISO8601](#NewISO8601)
|
||||
- [ToUnix](#ToUnix)
|
||||
- [ToFormat](#ToFormat)
|
||||
- [ToFormatForTpl](#ToFormatForTpl)
|
||||
- [ToIso8601](#ToIso8601)
|
||||
|
||||
|
||||
- [AddDay](#AddDay)
|
||||
- [AddHour](#AddHour)
|
||||
- [AddMinute](#AddMinute)
|
||||
- [BeginOfMinute](#BeginOfMinute)
|
||||
- [BeginOfHour](#BeginOfHour)
|
||||
- [BeginOfDay](#BeginOfDay)
|
||||
- [BeginOfWeek](#BeginOfWeek)
|
||||
- [BeginOfMonth](#BeginOfMonth)
|
||||
- [BeginOfYear](#BeginOfYear)
|
||||
- [EndOfMinute](#EndOfMinute)
|
||||
- [EndOfHour](#EndOfHour)
|
||||
- [EndOfDay](#EndOfDay)
|
||||
- [EndOfWeek](#EndOfWeek)
|
||||
- [EndOfMonth](#EndOfMonth)
|
||||
- [EndOfYear](#EndOfYear)
|
||||
- [GetNowDate](#GetNowDate)
|
||||
- [GetNowTime](#GetNowTime)
|
||||
- [GetNowDateTime](#GetNowDateTime)
|
||||
- [GetZeroHourTimestamp](#GetZeroHourTimestamp)
|
||||
- [GetNightTimestamp](#GetNightTimestamp)
|
||||
- [FormatTimeToStr](#FormatTimeToStr)
|
||||
- [FormatStrToTime](#FormatStrToTime)
|
||||
- [NewUnixNow](#NewUnixNow)
|
||||
- [NewUnix](#NewUnix)
|
||||
- [NewFormat](#NewFormat)
|
||||
- [NewISO8601](#NewISO8601)
|
||||
- [ToUnix](#ToUnix)
|
||||
- [ToFormat](#ToFormat)
|
||||
- [ToFormatForTpl](#ToFormatForTpl)
|
||||
- [ToIso8601](#ToIso8601)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
## Note:
|
||||
1. 'format' string param in func FormatTimeToStr and FormatStrToTime function should be one of flows:
|
||||
- yyyy-mm-dd hh:mm:ss
|
||||
- yyyy-mm-dd hh:mm
|
||||
- yyyy-mm-dd hh
|
||||
- yyyy-mm-dd
|
||||
- yyyy-mm
|
||||
- mm-dd
|
||||
- dd-mm-yy hh:mm:ss
|
||||
- yyyy/mm/dd hh:mm:ss
|
||||
- yyyy/mm/dd hh:mm
|
||||
- yyyy-mm-dd hh
|
||||
- yyyy/mm/dd
|
||||
- yyyy/mm
|
||||
- mm/dd
|
||||
- dd/mm/yy hh:mm:ss
|
||||
- yyyy
|
||||
- mm
|
||||
- hh:mm:ss
|
||||
- mm:ss
|
||||
|
||||
1. 'format' string param in func FormatTimeToStr and FormatStrToTime function should be one of flows:
|
||||
|
||||
- yyyy-mm-dd hh:mm:ss
|
||||
- yyyy-mm-dd hh:mm
|
||||
- yyyy-mm-dd hh
|
||||
- yyyy-mm-dd
|
||||
- yyyy-mm
|
||||
- mm-dd
|
||||
- dd-mm-yy hh:mm:ss
|
||||
- yyyy/mm/dd hh:mm:ss
|
||||
- yyyy/mm/dd hh:mm
|
||||
- yyyy-mm-dd hh
|
||||
- yyyy/mm/dd
|
||||
- yyyy/mm
|
||||
- mm/dd
|
||||
- dd/mm/yy hh:mm:ss
|
||||
- yyyy
|
||||
- mm
|
||||
- hh:mm:ss
|
||||
- mm:ss
|
||||
|
||||
### <span id="AddDay">AddDay</span>
|
||||
|
||||
<p>Add or sub days to time.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -87,6 +90,7 @@ import (
|
||||
```go
|
||||
func AddDay(t time.Time, day int64) time.Time
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -100,15 +104,24 @@ import (
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
after2Days := datetime.AddDay(now, 2)
|
||||
before2Days := datetime.AddDay(now, -2)
|
||||
|
||||
fmt.Println(after2Days, before2Days)
|
||||
tomorrow := datetime.AddDay(now, 1)
|
||||
diff1 := tomorrow.Sub(now)
|
||||
|
||||
yesterday := datetime.AddDay(now, -1)
|
||||
diff2 := yesterday.Sub(now)
|
||||
|
||||
fmt.Println(diff1)
|
||||
fmt.Println(diff2)
|
||||
|
||||
// Output:
|
||||
// 24h0m0s
|
||||
// -24h0m0s
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="AddHour">AddHour</span>
|
||||
|
||||
<p>Add or sub hours to time.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -116,6 +129,7 @@ func main() {
|
||||
```go
|
||||
func AddHour(t time.Time, hour int64) time.Time
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -129,14 +143,24 @@ import (
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
after2Hours := datetime.AddHour(now, 2)
|
||||
before2Hours := datetime.AddHour(now, -2)
|
||||
|
||||
fmt.Println(after2Hours, after2Hours)
|
||||
after2Hours := datetime.AddHour(now, 2)
|
||||
diff1 := after2Hours.Sub(now)
|
||||
|
||||
before2Hours := datetime.AddHour(now, -2)
|
||||
diff2 := before2Hours.Sub(now)
|
||||
|
||||
fmt.Println(diff1)
|
||||
fmt.Println(diff2)
|
||||
|
||||
// Output:
|
||||
// 2h0m0s
|
||||
// -2h0m0s
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="AddMinute">AddMinute</span>
|
||||
|
||||
<p>Add or sub minutes to time.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -144,6 +168,7 @@ func main() {
|
||||
```go
|
||||
func AddMinute(t time.Time, minute int64) time.Time
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -157,14 +182,24 @@ import (
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
after2Minute := datetime.AddMinute(now, 2)
|
||||
before2Minute := datetime.AddMinute(now, -2)
|
||||
|
||||
fmt.Println(after2Minute, before2Minute)
|
||||
after2Minutes := datetime.AddMinute(now, 2)
|
||||
diff1 := after2Minutes.Sub(now)
|
||||
|
||||
before2Minutes := datetime.AddMinute(now, -2)
|
||||
diff2 := before2Minutes.Sub(now)
|
||||
|
||||
fmt.Println(diff1)
|
||||
fmt.Println(diff2)
|
||||
|
||||
// Output:
|
||||
// 2m0s
|
||||
// -2m0s
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="BeginOfMinute">BeginOfMinute</span>
|
||||
|
||||
<p>Return beginning minute time of day.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -172,6 +207,7 @@ func main() {
|
||||
```go
|
||||
func BeginOfMinute(t time.Time) time.Time
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -184,13 +220,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.BeginOfMinute(td)
|
||||
fmt.Println(bm) //2022-02-15 15:48:00 +0800 CST
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
result := datetime.BeginOfMinute(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-01-08 18:50:00 +0000 UTC
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="BeginOfHour">BeginOfHour</span>
|
||||
|
||||
<p>Return zero time of day.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -198,6 +239,7 @@ func main() {
|
||||
```go
|
||||
func BeginOfHour(t time.Time) time.Time
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -210,13 +252,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.BeginOfHour(td)
|
||||
fmt.Println(bm) //2022-02-15 15:00:00 +0800 CST
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
result := datetime.BeginOfHour(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-01-08 18:00:00 +0000 UTC
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="BeginOfDay">BeginOfDay</span>
|
||||
|
||||
<p>Return begin time of day.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -224,6 +271,7 @@ func main() {
|
||||
```go
|
||||
func BeginOfDay(t time.Time) time.Time
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -236,15 +284,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.BeginOfDay(td)
|
||||
fmt.Println(bm) //2022-02-15 00:00:00 +0800 CST
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
result := datetime.BeginOfDay(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-01-08 00:00:00 +0000 UTC
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="BeginOfWeek">BeginOfWeek</span>
|
||||
|
||||
<p>Return beginning time of week, week begin from Sunday.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -252,6 +303,7 @@ func main() {
|
||||
```go
|
||||
func BeginOfWeek(t time.Time, beginFrom ...time.Weekday) time.Time
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -264,15 +316,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.BeginOfWeek(td)
|
||||
fmt.Println(bm) //2022-02-13 00:00:00 +0800 CST
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
result := datetime.BeginOfWeek(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-01-08 00:00:00 +0000 UTC
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="BeginOfMonth">BeginOfMonth</span>
|
||||
|
||||
<p>Return beginning time of month</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -280,6 +335,7 @@ func main() {
|
||||
```go
|
||||
func BeginOfMonth(t time.Time) time.Time
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -292,14 +348,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.BeginOfMonth(td)
|
||||
fmt.Println(bm) //2022-02-01 00:00:00 +0800 CST
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
result := datetime.BeginOfMonth(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-01-01 00:00:00 +0000 UTC
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="BeginOfYear">BeginOfYear</span>
|
||||
|
||||
<p>Return beginning time of year.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -307,6 +367,7 @@ func main() {
|
||||
```go
|
||||
func BeginOfYear(t time.Time) time.Time
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -319,15 +380,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.BeginOfYear(td)
|
||||
fmt.Println(bm) //2022-01-01 00:00:00 +0800 CST
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
result := datetime.BeginOfYear(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-01-01 00:00:00 +0000 UTC
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="EndOfMinute">EndOfMinute</span>
|
||||
|
||||
<p>Return end time minute of day.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -335,6 +399,7 @@ func main() {
|
||||
```go
|
||||
func EndOfMinute(t time.Time) time.Time
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -347,13 +412,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.EndOfMinute(td)
|
||||
fmt.Println(bm) //2022-02-15 15:48:59.999999999 +0800 CST
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
result := datetime.EndOfMinute(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-01-08 18:50:59.999999999 +0000 UTC
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="EndOfHour">EndOfHour</span>
|
||||
|
||||
<p>Return end time hour of day.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -361,6 +431,7 @@ func main() {
|
||||
```go
|
||||
func EndOfHour(t time.Time) time.Time
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -373,13 +444,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.EndOfHour(td)
|
||||
fmt.Println(bm) //2022-02-15 15:59:59.999999999 +0800 CST
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
result := datetime.EndOfHour(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-01-08 18:59:59.999999999 +0000 UTC
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="EndOfDay">EndOfDay</span>
|
||||
|
||||
<p>Return end time hour of day.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -387,6 +463,7 @@ func main() {
|
||||
```go
|
||||
func EndOfDay(t time.Time) time.Time
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -399,15 +476,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.EndOfDay(td)
|
||||
fmt.Println(bm) //2022-02-15 23:59:59.999999999 +0800 CST
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
result := datetime.EndOfDay(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-01-08 23:59:59.999999999 +0000 UTC
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="EndOfWeek">EndOfWeek</span>
|
||||
|
||||
<p>Return end time of week, week end with Saturday.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -415,6 +495,7 @@ func main() {
|
||||
```go
|
||||
func EndOfWeek(t time.Time, endWith ...time.Weekday) time.Time
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -427,15 +508,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.EndOfWeek(td)
|
||||
fmt.Println(bm) //2022-02-19 23:59:59.999999999 +0800 CST
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
result := datetime.EndOfWeek(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-01-14 23:59:59.999999999 +0000 UTC
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="EndOfMonth">EndOfMonth</span>
|
||||
|
||||
<p>Return end time of month</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -443,6 +527,7 @@ func main() {
|
||||
```go
|
||||
func EndOfMonth(t time.Time) time.Time
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -455,14 +540,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.EndOfMonth(td)
|
||||
fmt.Println(bm) //2022-02-28 23:59:59.999999999 +0800 CST
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
result := datetime.EndOfMonth(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-01-31 23:59:59.999999999 +0000 UTC
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="EndOfYear">EndOfYear</span>
|
||||
|
||||
<p>Return beginning time of year.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -470,6 +559,7 @@ func main() {
|
||||
```go
|
||||
func EndOfYear(t time.Time) time.Time
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -482,14 +572,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.EndOfYear(td)
|
||||
fmt.Println(bm) //2022-12-31 23:59:59.999999999 +0800 CST
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
result := datetime.EndOfYear(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-12-31 23:59:59.999999999 +0000 UTC
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="GetNowDate">GetNowDate</span>
|
||||
|
||||
<p>Get current date string, format is yyyy-mm-dd.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -497,6 +591,7 @@ func main() {
|
||||
```go
|
||||
func GetNowDate() string
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -511,12 +606,16 @@ import (
|
||||
func main() {
|
||||
now := time.Now()
|
||||
currentDate := datetime.GetNowDate()
|
||||
fmt.Println(currentDate) // 2022-01-28
|
||||
|
||||
fmt.Println(currentDate)
|
||||
|
||||
// Output:
|
||||
// 2022-01-28
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="GetNowTime">GetNowTime</span>
|
||||
|
||||
<p>Get current time string, format is hh:mm:ss.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -524,6 +623,7 @@ func main() {
|
||||
```go
|
||||
func GetNowTime() string
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -538,12 +638,16 @@ import (
|
||||
func main() {
|
||||
now := time.Now()
|
||||
currentTime := datetime.GetNowTime()
|
||||
fmt.Println(currentDate) // 15:57:33
|
||||
|
||||
fmt.Println(currentTime) // 15:57:33
|
||||
|
||||
// Output:
|
||||
// 15:57:33
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="GetNowDateTime">GetNowDateTime</span>
|
||||
|
||||
<p>Get current date time string, format is yyyy-mm-dd hh:mm:ss.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -551,6 +655,7 @@ func main() {
|
||||
```go
|
||||
func GetNowDateTime() string
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -565,12 +670,16 @@ import (
|
||||
func main() {
|
||||
now := time.Now()
|
||||
current := datetime.GetNowDateTime()
|
||||
fmt.Println(current) // 2022-01-28 15:59:33
|
||||
|
||||
fmt.Println(current)
|
||||
|
||||
// Output:
|
||||
// 2022-01-28 15:59:33
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="GetZeroHourTimestamp">GetZeroHourTimestamp</span>
|
||||
|
||||
<p>Return timestamp of zero hour (timestamp of 00:00).</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -578,6 +687,7 @@ func main() {
|
||||
```go
|
||||
func GetZeroHourTimestamp() int64
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -592,12 +702,16 @@ import (
|
||||
func main() {
|
||||
now := time.Now()
|
||||
zeroTime := datetime.GetZeroHourTimestamp()
|
||||
fmt.Println(zeroTime) // 1643299200
|
||||
|
||||
fmt.Println(zeroTime)
|
||||
|
||||
// Output:
|
||||
// 1643299200
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="GetNightTimestamp">GetNightTimestamp</span>
|
||||
|
||||
<p>Return timestamp of zero hour (timestamp of 23:59).</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -605,6 +719,7 @@ func main() {
|
||||
```go
|
||||
func GetNightTimestamp() int64
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -619,11 +734,16 @@ import (
|
||||
func main() {
|
||||
now := time.Now()
|
||||
nightTime := datetime.GetNightTimestamp()
|
||||
fmt.Println(nightTime) // 1643385599
|
||||
|
||||
fmt.Println(nightTime)
|
||||
|
||||
// Output:
|
||||
// 1643385599
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="FormatTimeToStr">FormatTimeToStr</span>
|
||||
|
||||
<p>Format time to string, `format` param specification see note 1.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -631,6 +751,7 @@ func main() {
|
||||
```go
|
||||
func FormatTimeToStr(t time.Time, format string) string
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -643,14 +764,25 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
timeStr := datetime.FormatTimeToStr(now, "yyyy/mm/dd hh:mm:ss")
|
||||
fmt.Println(timeStr) //2022/01/28 16:07:44
|
||||
t, _ := time.Parse("2006-01-02 15:04:05", "2021-01-02 16:04:08")
|
||||
|
||||
result1 := datetime.FormatTimeToStr(t, "yyyy-mm-dd hh:mm:ss")
|
||||
result2 := datetime.FormatTimeToStr(t, "yyyy-mm-dd")
|
||||
result3 := datetime.FormatTimeToStr(t, "dd-mm-yy hh:mm:ss")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// 2021-01-02 16:04:08
|
||||
// 2021-01-02
|
||||
// 02-01-21 16:04:08
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="FormatStrToTime">FormatStrToTime</span>
|
||||
|
||||
<p>Format string to time, `format` param specification see note 1.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -658,6 +790,7 @@ func main() {
|
||||
```go
|
||||
func FormatStrToTime(str, format string) (time.Time, error)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -669,24 +802,34 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
time := datetime.FormatStrToTime("2006-01-02 15:04:05", "yyyy/mm/dd hh:mm:ss")
|
||||
fmt.Println(time)
|
||||
result1, _ := datetime.FormatStrToTime("2021-01-02 16:04:08", "yyyy-mm-dd hh:mm:ss")
|
||||
result2, _ := datetime.FormatStrToTime("2021-01-02", "yyyy-mm-dd")
|
||||
result3, _ := datetime.FormatStrToTime("02-01-21 16:04:08", "dd-mm-yy hh:mm:ss")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// 2021-01-02 16:04:08 +0000 UTC
|
||||
// 2021-01-02 00:00:00 +0000 UTC
|
||||
// 2021-01-02 16:04:08 +0000 UTC
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="NewUnixNow">NewUnixNow</span>
|
||||
|
||||
<p>Return unix timestamp of current time</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
type theTime struct {
|
||||
unix int64
|
||||
unix int64
|
||||
}
|
||||
func NewUnixNow() *theTime
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -699,12 +842,15 @@ import (
|
||||
|
||||
func main() {
|
||||
tm := datetime.NewUnixNow()
|
||||
fmt.Println(tm) //&{1647597438}
|
||||
fmt.Println(tm)
|
||||
|
||||
// Output:
|
||||
// &{1647597438}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="NewUnix">NewUnix</span>
|
||||
|
||||
<p>Return unix timestamp of specified int64 value.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -715,6 +861,7 @@ type theTime struct {
|
||||
}
|
||||
func NewUnix(unix int64) *theTime
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -727,13 +874,15 @@ import (
|
||||
|
||||
func main() {
|
||||
tm := datetime.NewUnix(1647597438)
|
||||
fmt.Println(tm) //&{1647597438}
|
||||
fmt.Println(tm)
|
||||
|
||||
// Output:
|
||||
// &{1647597438}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="NewFormat">NewFormat</span>
|
||||
|
||||
<p>Return unix timestamp of specified time string, t should be "yyyy-mm-dd hh:mm:ss".</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -744,6 +893,7 @@ type theTime struct {
|
||||
}
|
||||
func NewFormat(t string) (*theTime, error)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -756,14 +906,15 @@ import (
|
||||
|
||||
func main() {
|
||||
tm, err := datetime.NewFormat("2022-03-18 17:04:05")
|
||||
fmt.Println(tm) //&{1647594245}
|
||||
fmt.Println(tm)
|
||||
|
||||
// Output:
|
||||
// &{1647594245}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="NewISO8601">NewISO8601</span>
|
||||
|
||||
<p>Return unix timestamp of specified iso8601 time string.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -774,6 +925,7 @@ type theTime struct {
|
||||
}
|
||||
func NewISO8601(iso8601 string) (*theTime, error)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -786,13 +938,15 @@ import (
|
||||
|
||||
func main() {
|
||||
tm, err := datetime.NewISO8601("2006-01-02T15:04:05.999Z")
|
||||
fmt.Println(tm) //&{1136214245}
|
||||
fmt.Println(tm)
|
||||
|
||||
// Output:
|
||||
// &{1136214245}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToUnix">ToUnix</span>
|
||||
|
||||
<p>Return unix timestamp.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -800,6 +954,7 @@ func main() {
|
||||
```go
|
||||
func (t *theTime) ToUnix() int64
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -812,13 +967,15 @@ import (
|
||||
|
||||
func main() {
|
||||
tm := datetime.NewUnixNow()
|
||||
fmt.Println(tm.ToUnix()) //1647597438
|
||||
fmt.Println(tm.ToUnix())
|
||||
|
||||
// Output:
|
||||
// 1647597438
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToFormat">ToFormat</span>
|
||||
|
||||
<p>Return time string 'yyyy-mm-dd hh:mm:ss'.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -826,6 +983,7 @@ func main() {
|
||||
```go
|
||||
func (t *theTime) ToFormat() string
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -838,13 +996,15 @@ import (
|
||||
|
||||
func main() {
|
||||
tm, _ := datetime.NewFormat("2022-03-18 17:04:05")
|
||||
fmt.Println(tm.ToFormat()) //"2022-03-18 17:04:05"
|
||||
fmt.Println(tm.ToFormat())
|
||||
|
||||
// Output:
|
||||
// 2022-03-18 17:04:05
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToFormatForTpl">ToFormatForTpl</span>
|
||||
|
||||
<p>Return the time string which format is specified tpl.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -852,6 +1012,7 @@ func main() {
|
||||
```go
|
||||
func (t *theTime) ToFormatForTpl(tpl string) string
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -865,12 +1026,15 @@ import (
|
||||
func main() {
|
||||
tm, _ := datetime.NewFormat("2022-03-18 17:04:05")
|
||||
ts := tm.ToFormatForTpl("2006/01/02 15:04:05")
|
||||
fmt.Println(ts) //"2022/03/18 17:04:05"
|
||||
fmt.Println(ts)
|
||||
|
||||
// Output:
|
||||
// 2022/03/18 17:04:05
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="ToIso8601">ToIso8601</span>
|
||||
|
||||
<p>Return iso8601 time string.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -878,6 +1042,7 @@ func main() {
|
||||
```go
|
||||
func (t *theTime) ToIso8601() string
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -891,6 +1056,9 @@ import (
|
||||
func main() {
|
||||
tm, _ := datetime.NewISO8601("2006-01-02T15:04:05.999Z")
|
||||
ts := tm.ToIso8601()
|
||||
fmt.Println(ts) //"2006-01-02T23:04:05+08:00"
|
||||
fmt.Println(ts)
|
||||
|
||||
// Output:
|
||||
// 2006-01-02T23:04:05+08:00
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
102
docs/fileutil.md
102
docs/fileutil.md
@@ -1,15 +1,17 @@
|
||||
# Fileutil
|
||||
|
||||
Package fileutil implements some basic functions for file operations.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/fileutil/file.go](https://github.com/duke-git/lancet/blob/main/fileutil/file.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/fileutil/file.go](https://github.com/duke-git/lancet/blob/main/fileutil/file.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Usage:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
@@ -19,30 +21,30 @@ import (
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [ClearFile](#ClearFile)
|
||||
- [CreateFile](#CreateFile)
|
||||
- [CreateDir](#CreateDir)
|
||||
- [CopyFile](#CopyFile)
|
||||
- [FileMode](#FileMode)
|
||||
- [MiMeType](#MiMeType)
|
||||
- [IsExist](#IsExist)
|
||||
- [IsLink](#IsLink)
|
||||
- [IsDir](#IsDir)
|
||||
- [ListFileNames](#ListFileNames)
|
||||
- [RemoveFile](#RemoveFile)
|
||||
- [ReadFileToString](#ReadFileToString)
|
||||
- [ReadFileByLine](#ReadFileByLine)
|
||||
- [Zip](#Zip)
|
||||
- [UnZip](#UnZip)
|
||||
- [UnZip](#UnZip)
|
||||
|
||||
- [ClearFile](#ClearFile)
|
||||
- [CreateFile](#CreateFile)
|
||||
- [CreateDir](#CreateDir)
|
||||
- [CopyFile](#CopyFile)
|
||||
- [FileMode](#FileMode)
|
||||
- [MiMeType](#MiMeType)
|
||||
- [IsExist](#IsExist)
|
||||
- [IsLink](#IsLink)
|
||||
- [IsDir](#IsDir)
|
||||
- [ListFileNames](#ListFileNames)
|
||||
- [RemoveFile](#RemoveFile)
|
||||
- [ReadFileToString](#ReadFileToString)
|
||||
- [ReadFileByLine](#ReadFileByLine)
|
||||
- [Zip](#Zip)
|
||||
- [UnZip](#UnZip)
|
||||
- [UnZip](#UnZip)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
|
||||
### <span id="ClearFile">ClearFile</span>
|
||||
|
||||
<p>Clear the file content, write empty string to the file.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -50,6 +52,7 @@ import (
|
||||
```go
|
||||
func ClearFile(path string) error
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -69,6 +72,7 @@ func main() {
|
||||
```
|
||||
|
||||
### <span id="CreateFile">CreateFile</span>
|
||||
|
||||
<p>Create file in path. return true if create succeed.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -76,6 +80,7 @@ func main() {
|
||||
```go
|
||||
func CreateFile(path string) bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -92,9 +97,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="CreateDir">CreateDir</span>
|
||||
|
||||
<p>Create directory in absolute path. param `absPath` like /a/, /a/b/.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -102,6 +106,7 @@ func main() {
|
||||
```go
|
||||
func CreateDir(absPath string) error
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -118,8 +123,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="CopyFile">CopyFile</span>
|
||||
|
||||
<p>Copy src file to dest file. If dest file exist will overwrite it.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -127,6 +132,7 @@ func main() {
|
||||
```go
|
||||
func CopyFile(srcFilePath string, dstFilePath string) error
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -145,9 +151,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="FileMode">FileMode</span>
|
||||
|
||||
<p>Return file mode infomation.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -155,6 +160,7 @@ func main() {
|
||||
```go
|
||||
func FileMode(path string) (fs.FileMode, error)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -174,9 +180,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="MiMeType">MiMeType</span>
|
||||
|
||||
<p>Get file mime type, 'file' param's type should be string or *os.File.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -184,6 +189,7 @@ func main() {
|
||||
```go
|
||||
func MiMeType(file any) string
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -205,10 +211,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsExist">IsExist</span>
|
||||
|
||||
<p>Checks if a file or directory exists.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -216,6 +220,7 @@ func main() {
|
||||
```go
|
||||
func IsExist(path string) bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -233,9 +238,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="IsLink">IsLink</span>
|
||||
|
||||
<p>Checks if a file is symbol link or not.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -243,6 +247,7 @@ func main() {
|
||||
```go
|
||||
func IsLink(path string) bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -259,16 +264,16 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="IsDir">IsDir</span>
|
||||
|
||||
<p>Checks if the path is directy or not.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsDir(path string) bool
|
||||
func IsDir(path string) bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -288,9 +293,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ListFileNames">ListFileNames</span>
|
||||
|
||||
<p>List all file names in given path.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -298,6 +302,7 @@ func main() {
|
||||
```go
|
||||
func ListFileNames(path string) ([]string, error)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -314,9 +319,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="RemoveFile">RemoveFile</span>
|
||||
|
||||
<p>Remove the file of path.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -324,6 +328,7 @@ func main() {
|
||||
```go
|
||||
func RemoveFile(path string) error
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -342,8 +347,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="ReadFileToString">ReadFileToString</span>
|
||||
|
||||
<p>Return string of file content.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -351,6 +356,7 @@ func main() {
|
||||
```go
|
||||
func ReadFileToString(path string) (string, error)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -374,9 +380,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ReadFileByLine">ReadFileByLine</span>
|
||||
|
||||
<p>Read file line by line, and return slice of lines</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -384,6 +389,7 @@ func main() {
|
||||
```go
|
||||
func ReadFileByLine(path string)([]string, error)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -408,9 +414,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Zip">Zip</span>
|
||||
|
||||
<p>Create a zip file of fpath, fpath could be a file or a directory.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -418,6 +423,7 @@ func main() {
|
||||
```go
|
||||
func Zip(fpath string, destPath string) error
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -436,10 +442,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="UnZip">UnZip</span>
|
||||
|
||||
<p>Unzip the file and save it to dest path.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -447,6 +451,7 @@ func main() {
|
||||
```go
|
||||
func UnZip(zipFile string, destPath string) error
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -464,8 +469,3 @@ func main() {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
# Fileutil
|
||||
fileutil包支持文件基本操作。
|
||||
|
||||
fileutil 包支持文件基本操作。
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/fileutil/file.go](https://github.com/duke-git/lancet/blob/main/fileutil/file.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/fileutil/file.go](https://github.com/duke-git/lancet/blob/main/fileutil/file.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
@@ -19,29 +21,29 @@ import (
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录
|
||||
- [ClearFile](#ClearFile)
|
||||
- [CreateFile](#CreateFile)
|
||||
- [CreateDir](#CreateDir)
|
||||
- [CopyFile](#CopyFile)
|
||||
- [FileMode](#FileMode)
|
||||
- [MiMeType](#MiMeType)
|
||||
- [IsExist](#IsExist)
|
||||
- [IsLink](#IsLink)
|
||||
- [IsDir](#IsDir)
|
||||
- [ListFileNames](#ListFileNames)
|
||||
- [RemoveFile](#RemoveFile)
|
||||
- [ReadFileToString](#ReadFileToString)
|
||||
- [ReadFileByLine](#ReadFileByLine)
|
||||
- [Zip](#Zip)
|
||||
- [UnZip](#UnZip)
|
||||
|
||||
- [ClearFile](#ClearFile)
|
||||
- [CreateFile](#CreateFile)
|
||||
- [CreateDir](#CreateDir)
|
||||
- [CopyFile](#CopyFile)
|
||||
- [FileMode](#FileMode)
|
||||
- [MiMeType](#MiMeType)
|
||||
- [IsExist](#IsExist)
|
||||
- [IsLink](#IsLink)
|
||||
- [IsDir](#IsDir)
|
||||
- [ListFileNames](#ListFileNames)
|
||||
- [RemoveFile](#RemoveFile)
|
||||
- [ReadFileToString](#ReadFileToString)
|
||||
- [ReadFileByLine](#ReadFileByLine)
|
||||
- [Zip](#Zip)
|
||||
- [UnZip](#UnZip)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 文档
|
||||
|
||||
|
||||
|
||||
### <span id="ClearFile">ClearFile</span>
|
||||
|
||||
<p>清空文件内容</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -49,7 +51,8 @@ import (
|
||||
```go
|
||||
func ClearFile(path string) error
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -68,6 +71,7 @@ func main() {
|
||||
```
|
||||
|
||||
### <span id="CreateFile">CreateFile</span>
|
||||
|
||||
<p>创建文件,创建成功返回true, 否则返回false</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -75,7 +79,8 @@ func main() {
|
||||
```go
|
||||
func CreateFile(path string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -91,8 +96,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="CreateDir">CreateDir</span>
|
||||
|
||||
<p>使用绝对路径创建嵌套目录,例如/a/, /a/b/</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -100,6 +105,7 @@ func main() {
|
||||
```go
|
||||
func CreateDir(absPath string) error
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -116,9 +122,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="CopyFile">CopyFile</span>
|
||||
|
||||
<p>拷贝文件,会覆盖原有的文件</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -126,7 +131,8 @@ func main() {
|
||||
```go
|
||||
func CopyFile(srcFilePath string, dstFilePath string) error
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -144,9 +150,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="FileMode">FileMode</span>
|
||||
|
||||
<p>获取文件mode信息</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -154,7 +159,8 @@ func main() {
|
||||
```go
|
||||
func FileMode(path string) (fs.FileMode, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -173,9 +179,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="MiMeType">MiMeType</span>
|
||||
|
||||
<p>获取文件mime类型, 'file'参数的类型必须是string或者*os.File</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -183,7 +188,8 @@ func main() {
|
||||
```go
|
||||
func MiMeType(file any) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -204,10 +210,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsExist">IsExist</span>
|
||||
|
||||
<p>判断文件或目录是否存在</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -215,7 +219,8 @@ func main() {
|
||||
```go
|
||||
func IsExist(path string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -232,9 +237,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="IsLink">IsLink</span>
|
||||
|
||||
<p>判断文件是否是符号链接</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -242,7 +246,8 @@ func main() {
|
||||
```go
|
||||
func IsLink(path string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -258,17 +263,17 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="IsDir">IsDir</span>
|
||||
|
||||
<p>判断参数是否是目录</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsDir(path string) bool
|
||||
func IsDir(path string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -287,9 +292,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ListFileNames">ListFileNames</span>
|
||||
|
||||
<p>返回目录下所有文件名</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -297,7 +301,8 @@ func main() {
|
||||
```go
|
||||
func ListFileNames(path string) ([]string, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -313,9 +318,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="RemoveFile">RemoveFile</span>
|
||||
|
||||
<p>删除文件</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -323,7 +327,8 @@ func main() {
|
||||
```go
|
||||
func RemoveFile(path string) error
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -341,8 +346,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="ReadFileToString">ReadFileToString</span>
|
||||
|
||||
<p>读取文件内容并返回字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -350,7 +355,8 @@ func main() {
|
||||
```go
|
||||
func ReadFileToString(path string) (string, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -373,9 +379,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ReadFileByLine">ReadFileByLine</span>
|
||||
|
||||
<p>按行读取文件内容,返回字符串切片包含每一行</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -383,7 +388,8 @@ func main() {
|
||||
```go
|
||||
func ReadFileByLine(path string)([]string, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -407,9 +413,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Zip">Zip</span>
|
||||
|
||||
<p>zip压缩文件, fpath参数可以是文件或目录</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -417,7 +422,8 @@ func main() {
|
||||
```go
|
||||
func Zip(fpath string, destPath string) error
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -435,10 +441,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="UnZip">UnZip</span>
|
||||
|
||||
<p>zip解压缩文件并保存在目录中</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -446,7 +450,8 @@ func main() {
|
||||
```go
|
||||
func UnZip(zipFile string, destPath string) error
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -463,8 +468,3 @@ func main() {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
# Formatter
|
||||
|
||||
formatter contains some functions for data formatting.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/formatter/formatter.go](https://github.com/duke-git/lancet/blob/main/formatter/formatter.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/formatter/formatter.go](https://github.com/duke-git/lancet/blob/main/formatter/formatter.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Usage:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/formatter"
|
||||
@@ -19,15 +21,15 @@ import (
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [Comma](#Comma)
|
||||
|
||||
- [Comma](#Comma)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
|
||||
### <span id="Comma">Comma</span>
|
||||
|
||||
<p>Add comma to a number value by every 3 numbers from right to left. ahead by symbol char. if value is a invalid number string like "aa", return empty string.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -35,6 +37,7 @@ import (
|
||||
```go
|
||||
func Comma[T constraints.Float | constraints.Integer | string](value T, symbol string) string
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -46,7 +49,17 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(formatter.Comma("12345", "")) // "12,345"
|
||||
fmt.Println(formatter.Comma(12345.67, "¥")) // "¥12,345.67"
|
||||
result1 := formatter.Comma("123", "")
|
||||
result2 := formatter.Comma("12345", "$")
|
||||
result3 := formatter.Comma(1234567, "¥")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// 123
|
||||
// $12,345
|
||||
// ¥1,234,567
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
# Formatter
|
||||
formatter格式化器包含一些数据格式化处理方法。
|
||||
|
||||
formatter 格式化器包含一些数据格式化处理方法。
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/formatter/formatter.go](https://github.com/duke-git/lancet/blob/main/formatter/formatter.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/formatter/formatter.go](https://github.com/duke-git/lancet/blob/main/formatter/formatter.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/formatter"
|
||||
@@ -19,15 +21,15 @@ import (
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录
|
||||
- [Comma](#Comma)
|
||||
|
||||
- [Comma](#Comma)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 文档
|
||||
|
||||
|
||||
|
||||
### <span id="Comma">Comma</span>
|
||||
|
||||
<p>用逗号每隔3位分割数字/字符串,支持前缀添加符号。参数value必须是数字或者可以转为数字的字符串, 否则返回空字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -35,7 +37,8 @@ import (
|
||||
```go
|
||||
func Comma[T constraints.Float | constraints.Integer | string](value T, symbol string) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -46,7 +49,17 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(formatter.Comma("12345", "")) // "12,345"
|
||||
fmt.Println(formatter.Comma(12345.67, "¥")) // "¥12,345.67"
|
||||
result1 := formatter.Comma("123", "")
|
||||
result2 := formatter.Comma("12345", "$")
|
||||
result3 := formatter.Comma(1234567, "¥")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// 123
|
||||
// $12,345
|
||||
// ¥1,234,567
|
||||
}
|
||||
```
|
||||
|
||||
270
docs/function.md
270
docs/function.md
@@ -1,16 +1,18 @@
|
||||
# Function
|
||||
|
||||
Package function can control the flow of function execution and support part of functional programming.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/function/function.go](https://github.com/duke-git/lancet/blob/main/function/function.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/function/watcher.go](https://github.com/duke-git/lancet/blob/main/function/watcher.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/function/function.go](https://github.com/duke-git/lancet/blob/main/function/function.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/function/watcher.go](https://github.com/duke-git/lancet/blob/main/function/watcher.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Usage:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/function"
|
||||
@@ -20,22 +22,22 @@ import (
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [After](#After)
|
||||
- [Before](#Before)
|
||||
- [CurryFn](#CurryFn)
|
||||
- [Compose](#Compose)
|
||||
- [Debounced](#Debounced)
|
||||
- [Delay](#Delay)
|
||||
- [Pipeline](#Pipeline)
|
||||
- [Watcher](#Watcher)
|
||||
|
||||
- [After](#After)
|
||||
- [Before](#Before)
|
||||
- [CurryFn](#CurryFn)
|
||||
- [Compose](#Compose)
|
||||
- [Debounced](#Debounced)
|
||||
- [Delay](#Delay)
|
||||
- [Pipeline](#Pipeline)
|
||||
- [Watcher](#Watcher)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
|
||||
### <span id="After">After</span>
|
||||
|
||||
<p>Creates a function that invokes given func once it's called n or more times.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -43,6 +45,7 @@ import (
|
||||
```go
|
||||
func After(n int, fn any) func(args ...any) []reflect.Value
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -54,33 +57,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
arr := []string{"a", "b"}
|
||||
f := function.After(len(arr), func(i int) int {
|
||||
fmt.Println("last print")
|
||||
return i
|
||||
})
|
||||
fn := function.After(2, func() {
|
||||
fmt.Println("hello")
|
||||
})
|
||||
|
||||
type cb func(args ...any) []reflect.Value
|
||||
print := func(i int, s string, fn cb) {
|
||||
fmt.Printf("arr[%d] is %s \n", i, s)
|
||||
fn(i)
|
||||
}
|
||||
fn()
|
||||
fn()
|
||||
|
||||
fmt.Println("arr is", arr)
|
||||
for i := 0; i < len(arr); i++ {
|
||||
print(i, arr[i], f)
|
||||
}
|
||||
|
||||
//output:
|
||||
// arr is [a b]
|
||||
// arr[0] is a
|
||||
// arr[1] is b
|
||||
// last print
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Before">Before</span>
|
||||
|
||||
<p>creates a function that invokes func once it's called less than n times.</p>
|
||||
@@ -90,6 +78,7 @@ func main() {
|
||||
```go
|
||||
func Before(n int, fn any) func(args ...any) []reflect.Value
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -102,29 +91,21 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
arr := []string{"a", "b", "c", "d", "e"}
|
||||
f := function.Before(3, func(i int) int {
|
||||
return i
|
||||
})
|
||||
fn := function.Before(2, func() {
|
||||
fmt.Println("hello")
|
||||
})
|
||||
|
||||
var res []int64
|
||||
type cb func(args ...any) []reflect.Value
|
||||
appendStr := func(i int, s string, fn cb) {
|
||||
v := fn(i)
|
||||
res = append(res, v[0].Int())
|
||||
}
|
||||
fn()
|
||||
fn()
|
||||
fn()
|
||||
fn()
|
||||
|
||||
for i := 0; i < len(arr); i++ {
|
||||
appendStr(i, arr[i], f)
|
||||
}
|
||||
|
||||
expected := []int64{0, 1, 2, 2, 2}
|
||||
fmt.Println(res) // 0, 1, 2, 2, 2
|
||||
// Output:
|
||||
// hello
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="CurryFn">CurryFn</span>
|
||||
|
||||
<p>Make curry function.</p>
|
||||
@@ -135,6 +116,7 @@ func main() {
|
||||
type CurryFn[T any] func(...T) T
|
||||
func (cf CurryFn[T]) New(val T) func(...T) T
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -147,22 +129,23 @@ import (
|
||||
|
||||
func main() {
|
||||
add := func(a, b int) int {
|
||||
return a + b
|
||||
}
|
||||
return a + b
|
||||
}
|
||||
|
||||
var addCurry CurryFn[int] = func(values ...int) int {
|
||||
return add(values[0], values[1])
|
||||
}
|
||||
add1 := addCurry.New(1)
|
||||
var addCurry function.CurryFn[int] = func(values ...int) int {
|
||||
return add(values[0], values[1])
|
||||
}
|
||||
add1 := addCurry.New(1)
|
||||
|
||||
result := add1(2)
|
||||
result := add1(2)
|
||||
|
||||
fmt.Println(result) //3
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Compose">Compose</span>
|
||||
|
||||
<p>Compose the function list from right to left, then return the composed function.</p>
|
||||
@@ -172,6 +155,7 @@ func main() {
|
||||
```go
|
||||
func Compose[T any](fnList ...func(...T) T) func(...T) T
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -183,22 +167,23 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
toUpper := func(strs ...string) string {
|
||||
return strings.ToUpper(strs[0])
|
||||
}
|
||||
toLower := func(strs ...string) string {
|
||||
return strings.ToLower(strs[0])
|
||||
}
|
||||
transform := Compose(toUpper, toLower)
|
||||
toUpper := func(strs ...string) string {
|
||||
return strings.ToUpper(strs[0])
|
||||
}
|
||||
toLower := func(strs ...string) string {
|
||||
return strings.ToLower(strs[0])
|
||||
}
|
||||
transform := function.Compose(toUpper, toLower)
|
||||
|
||||
result := transform("aBCde")
|
||||
result := transform("aBCde")
|
||||
|
||||
fmt.Println(result) //ABCDE
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// ABCDE
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Debounced">Debounced</span>
|
||||
|
||||
<p>Creates a debounced function that delays invoking fn until after wait duration have elapsed since the last time the debounced function was invoked.</p>
|
||||
@@ -208,6 +193,7 @@ func main() {
|
||||
```go
|
||||
func Debounced(fn func(), duration time.Duration) func()
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -220,27 +206,34 @@ import (
|
||||
|
||||
func main() {
|
||||
count := 0
|
||||
add := func() {
|
||||
count++
|
||||
}
|
||||
|
||||
debouncedAdd := function.Debounced(add, 50*time.Microsecond)
|
||||
function.debouncedAdd()
|
||||
function.debouncedAdd()
|
||||
function.debouncedAdd()
|
||||
function.debouncedAdd()
|
||||
add := func() {
|
||||
count++
|
||||
}
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
fmt.Println(count) //1
|
||||
debouncedAdd := function.Debounced(add, 50*time.Microsecond)
|
||||
|
||||
function.debouncedAdd()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
fmt.Println(count) //2
|
||||
debouncedAdd()
|
||||
debouncedAdd()
|
||||
debouncedAdd()
|
||||
debouncedAdd()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
fmt.Println(count)
|
||||
|
||||
debouncedAdd()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
fmt.Println(count)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Delay">Delay</span>
|
||||
|
||||
<p>Invoke function after delayed time.</p>
|
||||
@@ -250,6 +243,7 @@ func main() {
|
||||
```go
|
||||
func Delay(delay time.Duration, fn any, args ...any)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -261,15 +255,17 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
var print = func(s string) {
|
||||
fmt.Println(count) //delay 2 seconds
|
||||
}
|
||||
function.Delay(2*time.Second, print, "delay 2 seconds")
|
||||
var print = func(s string) {
|
||||
fmt.Println(s)
|
||||
}
|
||||
|
||||
function.Delay(2*time.Second, print, "hello")
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Schedule">Schedule</span>
|
||||
|
||||
<p>Invoke function every duration time, until close the returned bool chan.</p>
|
||||
@@ -279,6 +275,7 @@ func main() {
|
||||
```go
|
||||
func Schedule(d time.Duration, fn any, args ...any) chan bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -290,20 +287,24 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
var res []string
|
||||
appendStr := func(s string) {
|
||||
res = append(res, s)
|
||||
}
|
||||
count := 0
|
||||
|
||||
stop := function.Schedule(1*time.Second, appendStr, "*")
|
||||
time.Sleep(5 * time.Second)
|
||||
close(stop)
|
||||
increase := func() {
|
||||
count++
|
||||
}
|
||||
|
||||
fmt.Println(res) //[* * * * *]
|
||||
stop := function.Schedule(2*time.Second, increase)
|
||||
|
||||
time.Sleep(2 * time.Second)
|
||||
close(stop)
|
||||
|
||||
fmt.Println(count)
|
||||
|
||||
// Output:
|
||||
// 2
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="Pipeline">Pipeline</span>
|
||||
|
||||
<p>Pipeline takes a list of functions and returns a function whose param will be passed into
|
||||
@@ -314,6 +315,7 @@ the functions one by one.</p>
|
||||
```go
|
||||
func Pipeline[T any](funcs ...func(T) T) func(T) T
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -326,22 +328,26 @@ import (
|
||||
|
||||
func main() {
|
||||
addOne := func(x int) int {
|
||||
return x + 1
|
||||
}
|
||||
double := func(x int) int {
|
||||
return 2 * x
|
||||
}
|
||||
square := func(x int) int {
|
||||
return x * x
|
||||
}
|
||||
return x + 1
|
||||
}
|
||||
double := func(x int) int {
|
||||
return 2 * x
|
||||
}
|
||||
square := func(x int) int {
|
||||
return x * x
|
||||
}
|
||||
|
||||
fn := Pipeline(addOne, double, square)
|
||||
fn := function.Pipeline(addOne, double, square)
|
||||
|
||||
fmt.Println(fn(2)) //36
|
||||
result := fn(2)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 36
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="Watcher">Watcher</span>
|
||||
|
||||
<p>Watcher is used for record code excution time. can start/stop/reset the watch timer. get the elapsed time of function execution.</p>
|
||||
@@ -350,9 +356,9 @@ func main() {
|
||||
|
||||
```go
|
||||
type Watcher struct {
|
||||
startTime int64
|
||||
stopTime int64
|
||||
excuting bool
|
||||
startTime int64
|
||||
stopTime int64
|
||||
excuting bool
|
||||
}
|
||||
func NewWatcher() *Watcher
|
||||
func (w *Watcher) Start() //start the watcher
|
||||
@@ -360,6 +366,7 @@ func (w *Watcher) Stop() //stop the watcher
|
||||
func (w *Watcher) Reset() //reset the watcher
|
||||
func (w *Watcher) GetElapsedTime() time.Duration //get the elapsed time of function execution
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -371,31 +378,28 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
w := function.NewWatcher()
|
||||
w := function.NewWatcher()
|
||||
|
||||
w.Start()
|
||||
w.Start()
|
||||
|
||||
longRunningTask()
|
||||
longRunningTask()
|
||||
|
||||
fmt.Println(w.excuting) //true
|
||||
fmt.Println(w.excuting) //true
|
||||
|
||||
w.Stop()
|
||||
w.Stop()
|
||||
|
||||
eapsedTime := w.GetElapsedTime().Milliseconds()
|
||||
|
||||
fmt.Println(eapsedTime)
|
||||
eapsedTime := w.GetElapsedTime().Milliseconds()
|
||||
|
||||
w.Reset()
|
||||
fmt.Println(eapsedTime)
|
||||
|
||||
w.Reset()
|
||||
}
|
||||
|
||||
func longRunningTask() {
|
||||
var slice []int64
|
||||
for i := 0; i < 10000000; i++ {
|
||||
slice = append(slice, int64(i))
|
||||
}
|
||||
var slice []int64
|
||||
for i := 0; i < 10000000; i++ {
|
||||
slice = append(slice, int64(i))
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
# Function
|
||||
function函数包控制函数执行流程,包含部分函数式编程。
|
||||
|
||||
function 函数包控制函数执行流程,包含部分函数式编程。
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/function/function.go](https://github.com/duke-git/lancet/blob/main/function/function.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/function/watcher.go](https://github.com/duke-git/lancet/blob/main/function/watcher.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/function/function.go](https://github.com/duke-git/lancet/blob/main/function/function.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/function/watcher.go](https://github.com/duke-git/lancet/blob/main/function/watcher.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/function"
|
||||
@@ -20,22 +22,22 @@ import (
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录
|
||||
- [After](#After)
|
||||
- [Before](#Before)
|
||||
- [CurryFn](#CurryFn)
|
||||
- [Compose](#Compose)
|
||||
- [Debounced](#Debounced)
|
||||
- [Delay](#Delay)
|
||||
- [Pipeline](#Pipeline)
|
||||
- [Watcher](#Watcher)
|
||||
|
||||
- [After](#After)
|
||||
- [Before](#Before)
|
||||
- [CurryFn](#CurryFn)
|
||||
- [Compose](#Compose)
|
||||
- [Debounced](#Debounced)
|
||||
- [Delay](#Delay)
|
||||
- [Pipeline](#Pipeline)
|
||||
- [Watcher](#Watcher)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 文档
|
||||
|
||||
|
||||
|
||||
### <span id="After">After</span>
|
||||
|
||||
<p>创建一个函数,当他被调用n或更多次之后将马上触发fn</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -43,7 +45,8 @@ import (
|
||||
```go
|
||||
func After(n int, fn any) func(args ...any) []reflect.Value
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -54,33 +57,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
arr := []string{"a", "b"}
|
||||
f := function.After(len(arr), func(i int) int {
|
||||
fmt.Println("last print")
|
||||
return i
|
||||
})
|
||||
fn := function.After(2, func() {
|
||||
fmt.Println("hello")
|
||||
})
|
||||
|
||||
type cb func(args ...any) []reflect.Value
|
||||
print := func(i int, s string, fn cb) {
|
||||
fmt.Printf("arr[%d] is %s \n", i, s)
|
||||
fn(i)
|
||||
}
|
||||
fn()
|
||||
fn()
|
||||
|
||||
fmt.Println("arr is", arr)
|
||||
for i := 0; i < len(arr); i++ {
|
||||
print(i, arr[i], f)
|
||||
}
|
||||
|
||||
//output:
|
||||
// arr is [a b]
|
||||
// arr[0] is a
|
||||
// arr[1] is b
|
||||
// last print
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Before">Before</span>
|
||||
|
||||
<p>创建一个函数,调用次数不超过n次,之后再调用这个函数,将返回一次最后调用fn的结果</p>
|
||||
@@ -90,7 +78,8 @@ func main() {
|
||||
```go
|
||||
func Before(n int, fn any) func(args ...any) []reflect.Value
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -102,28 +91,21 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
arr := []string{"a", "b", "c", "d", "e"}
|
||||
f := function.Before(3, func(i int) int {
|
||||
return i
|
||||
})
|
||||
fn := function.Before(2, func() {
|
||||
fmt.Println("hello")
|
||||
})
|
||||
|
||||
var res []int64
|
||||
type cb func(args ...any) []reflect.Value
|
||||
appendStr := func(i int, s string, fn cb) {
|
||||
v := fn(i)
|
||||
res = append(res, v[0].Int())
|
||||
}
|
||||
fn()
|
||||
fn()
|
||||
fn()
|
||||
fn()
|
||||
|
||||
for i := 0; i < len(arr); i++ {
|
||||
appendStr(i, arr[i], f)
|
||||
}
|
||||
|
||||
fmt.Println(res) // 0, 1, 2, 2, 2
|
||||
// Output:
|
||||
// hello
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="CurryFn">CurryFn</span>
|
||||
|
||||
<p>创建柯里化函数</p>
|
||||
@@ -134,7 +116,8 @@ func main() {
|
||||
type CurryFn[T any] func(...T) T
|
||||
func (cf CurryFn[T]) New(val T) func(...T) T
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -145,23 +128,24 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
add := func(a, b int) int {
|
||||
return a + b
|
||||
}
|
||||
add := func(a, b int) int {
|
||||
return a + b
|
||||
}
|
||||
|
||||
var addCurry CurryFn[int] = func(values ...int) int {
|
||||
return add(values[0], values[1])
|
||||
}
|
||||
add1 := addCurry.New(1)
|
||||
var addCurry function.CurryFn[int] = func(values ...int) int {
|
||||
return add(values[0], values[1])
|
||||
}
|
||||
add1 := addCurry.New(1)
|
||||
|
||||
result := add1(2)
|
||||
result := add1(2)
|
||||
|
||||
fmt.Println(result) //3
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Compose">Compose</span>
|
||||
|
||||
<p>从右至左组合函数列表fnList,返回组合后的函数</p>
|
||||
@@ -171,7 +155,8 @@ func main() {
|
||||
```go
|
||||
func Compose[T any](fnList ...func(...T) T) func(...T) T
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -182,22 +167,23 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
toUpper := func(strs ...string) string {
|
||||
return strings.ToUpper(strs[0])
|
||||
}
|
||||
toLower := func(strs ...string) string {
|
||||
return strings.ToLower(strs[0])
|
||||
}
|
||||
transform := Compose(toUpper, toLower)
|
||||
toUpper := func(strs ...string) string {
|
||||
return strings.ToUpper(strs[0])
|
||||
}
|
||||
toLower := func(strs ...string) string {
|
||||
return strings.ToLower(strs[0])
|
||||
}
|
||||
transform := function.Compose(toUpper, toLower)
|
||||
|
||||
result := transform("aBCde")
|
||||
result := transform("aBCde")
|
||||
|
||||
fmt.Println(result) //ABCDE
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// ABCDE
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Debounced">Debounced</span>
|
||||
|
||||
<p>创建一个debounced函数,该函数延迟调用fn直到自上次调用debounced函数后等待持续时间过去。</p>
|
||||
@@ -207,7 +193,8 @@ func main() {
|
||||
```go
|
||||
func Debounced(fn func(), duration time.Duration) func()
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -218,28 +205,35 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
count := 0
|
||||
add := func() {
|
||||
count++
|
||||
}
|
||||
count := 0
|
||||
|
||||
add := func() {
|
||||
count++
|
||||
}
|
||||
|
||||
debouncedAdd := function.Debounced(add, 50*time.Microsecond)
|
||||
function.debouncedAdd()
|
||||
function.debouncedAdd()
|
||||
function.debouncedAdd()
|
||||
function.debouncedAdd()
|
||||
debouncedAdd := function.Debounced(add, 50*time.Microsecond)
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
fmt.Println(count) //1
|
||||
debouncedAdd()
|
||||
debouncedAdd()
|
||||
debouncedAdd()
|
||||
debouncedAdd()
|
||||
|
||||
function.debouncedAdd()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
fmt.Println(count) //2
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
fmt.Println(count)
|
||||
|
||||
debouncedAdd()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
fmt.Println(count)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Delay">Delay</span>
|
||||
|
||||
<p>延迟delay时间后调用函数</p>
|
||||
@@ -249,7 +243,8 @@ func main() {
|
||||
```go
|
||||
func Delay(delay time.Duration, fn any, args ...any)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -260,15 +255,17 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
var print = func(s string) {
|
||||
fmt.Println(count) //test delay
|
||||
}
|
||||
function.Delay(2*time.Second, print, "test delay")
|
||||
var print = func(s string) {
|
||||
fmt.Println(s)
|
||||
}
|
||||
|
||||
function.Delay(2*time.Second, print, "hello")
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Schedule">Schedule</span>
|
||||
|
||||
<p>每次持续时间调用函数,直到关闭返回的 bool chan</p>
|
||||
@@ -278,7 +275,8 @@ func main() {
|
||||
```go
|
||||
func Schedule(d time.Duration, fn any, args ...any) chan bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -289,21 +287,24 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
var res []string
|
||||
appendStr := func(s string) {
|
||||
res = append(res, s)
|
||||
}
|
||||
count := 0
|
||||
|
||||
stop := function.Schedule(1*time.Second, appendStr, "*")
|
||||
time.Sleep(5 * time.Second)
|
||||
close(stop)
|
||||
increase := func() {
|
||||
count++
|
||||
}
|
||||
|
||||
fmt.Println(res) //[* * * * *]
|
||||
stop := function.Schedule(2*time.Second, increase)
|
||||
|
||||
time.Sleep(2 * time.Second)
|
||||
close(stop)
|
||||
|
||||
fmt.Println(count)
|
||||
|
||||
// Output:
|
||||
// 2
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Pipeline">Pipeline</span>
|
||||
|
||||
<p>执行函数pipeline.</p>
|
||||
@@ -313,7 +314,8 @@ func main() {
|
||||
```go
|
||||
func Pipeline[T any](funcs ...func(T) T) func(T) T
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -325,23 +327,26 @@ import (
|
||||
|
||||
func main() {
|
||||
addOne := func(x int) int {
|
||||
return x + 1
|
||||
}
|
||||
double := func(x int) int {
|
||||
return 2 * x
|
||||
}
|
||||
square := func(x int) int {
|
||||
return x * x
|
||||
}
|
||||
return x + 1
|
||||
}
|
||||
double := func(x int) int {
|
||||
return 2 * x
|
||||
}
|
||||
square := func(x int) int {
|
||||
return x * x
|
||||
}
|
||||
|
||||
f := Pipeline(addOne, double, square)
|
||||
fn := function.Pipeline(addOne, double, square)
|
||||
|
||||
fmt.Println(fn(2)) //36
|
||||
result := fn(2)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 36
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Watcher">Watcher</span>
|
||||
|
||||
<p>Watcher用于记录代码执行时间。可以启动/停止/重置手表定时器。获取函数执行的时间。</p>
|
||||
@@ -350,9 +355,9 @@ func main() {
|
||||
|
||||
```go
|
||||
type Watcher struct {
|
||||
startTime int64
|
||||
stopTime int64
|
||||
excuting bool
|
||||
startTime int64
|
||||
stopTime int64
|
||||
excuting bool
|
||||
}
|
||||
func NewWatcher() *Watcher
|
||||
func (w *Watcher) Start() //start the watcher
|
||||
@@ -360,7 +365,8 @@ func (w *Watcher) Stop() //stop the watcher
|
||||
func (w *Watcher) Reset() //reset the watcher
|
||||
func (w *Watcher) GetElapsedTime() time.Duration //get the elapsed time of function execution
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -373,30 +379,27 @@ import (
|
||||
func main() {
|
||||
w := function.NewWatcher()
|
||||
|
||||
w.Start()
|
||||
w.Start()
|
||||
|
||||
longRunningTask()
|
||||
longRunningTask()
|
||||
|
||||
fmt.Println(w.excuting) //true
|
||||
fmt.Println(w.excuting) //true
|
||||
|
||||
w.Stop()
|
||||
w.Stop()
|
||||
|
||||
eapsedTime := w.GetElapsedTime().Milliseconds()
|
||||
|
||||
fmt.Println(eapsedTime)
|
||||
eapsedTime := w.GetElapsedTime().Milliseconds()
|
||||
|
||||
w.Reset()
|
||||
fmt.Println(eapsedTime)
|
||||
|
||||
w.Reset()
|
||||
|
||||
}
|
||||
|
||||
func longRunningTask() {
|
||||
var slice []int64
|
||||
for i := 0; i < 10000000; i++ {
|
||||
slice = append(slice, int64(i))
|
||||
}
|
||||
var slice []int64
|
||||
for i := 0; i < 10000000; i++ {
|
||||
slice = append(slice, int64(i))
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
303
docs/maputil.md
303
docs/maputil.md
@@ -1,16 +1,17 @@
|
||||
# Maputil
|
||||
|
||||
Package maputil includes some functions to manipulate map.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/maputil/map.go](https://github.com/duke-git/lancet/blob/main/maputil/map.go)
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/maputil/map.go](https://github.com/duke-git/lancet/blob/main/maputil/map.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/maputil"
|
||||
@@ -20,22 +21,22 @@ import (
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [ForEach](#ForEach)
|
||||
- [Filter](#Filter)
|
||||
- [Intersect](#Intersect)
|
||||
- [Keys](#Keys)
|
||||
- [Merge](#Merge)
|
||||
- [Minus](#Minus)
|
||||
- [Values](#Values)
|
||||
- [IsDisjoint](#IsDisjoint)
|
||||
|
||||
- [ForEach](#ForEach)
|
||||
- [Filter](#Filter)
|
||||
- [Intersect](#Intersect)
|
||||
- [Keys](#Keys)
|
||||
- [Merge](#Merge)
|
||||
- [Minus](#Minus)
|
||||
- [Values](#Values)
|
||||
- [IsDisjoint](#IsDisjoint)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
|
||||
### <span id="ForEach">ForEach</span>
|
||||
|
||||
<p>Executes iteratee funcation for every key and value pair in map.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -43,6 +44,7 @@ import (
|
||||
```go
|
||||
func ForEach[K comparable, V any](m map[K]V, iteratee func(key K, value V))
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -54,26 +56,28 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
m := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3,
|
||||
"d": 4,
|
||||
}
|
||||
m := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3,
|
||||
"d": 4,
|
||||
}
|
||||
|
||||
var sum int
|
||||
var sum int
|
||||
|
||||
maputil.ForEach(m, func(_ string, value int) {
|
||||
sum += value
|
||||
})
|
||||
fmt.Println(sum) // 10
|
||||
maputil.ForEach(m, func(_ string, value int) {
|
||||
sum += value
|
||||
})
|
||||
|
||||
fmt.Println(sum)
|
||||
|
||||
// Output:
|
||||
// 10
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="Filter">Filter</span>
|
||||
|
||||
<p>Iterates over map, return a new map contains all key and value pairs pass the predicate function.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -81,6 +85,7 @@ func main() {
|
||||
```go
|
||||
func Filter[K comparable, V any](m map[K]V, predicate func(key K, value V) bool) map[K]V
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -92,29 +97,32 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
m := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3,
|
||||
"d": 4,
|
||||
"e": 5,
|
||||
}
|
||||
isEven := func(_ string, value int) bool {
|
||||
return value%2 == 0
|
||||
}
|
||||
m := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3,
|
||||
"d": 4,
|
||||
"e": 5,
|
||||
}
|
||||
isEven := func(_ string, value int) bool {
|
||||
return value%2 == 0
|
||||
}
|
||||
|
||||
maputil.Filter(m, func(_ string, value int) {
|
||||
sum += value
|
||||
})
|
||||
res := maputil.Filter(m, isEven)
|
||||
fmt.Println(res) // map[string]int{"b": 2, "d": 4,}
|
||||
maputil.Filter(m, func(_ string, value int) {
|
||||
sum += value
|
||||
})
|
||||
|
||||
result := maputil.Filter(m, isEven)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// map[b:2 d:4]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="Intersect">Intersect</span>
|
||||
|
||||
<p>Iterates over maps, return a new map of key and value pairs in all given maps.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -122,6 +130,7 @@ func main() {
|
||||
```go
|
||||
func Intersect[K comparable, V any](maps ...map[K]V) map[K]V
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -133,37 +142,42 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
m1 := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3,
|
||||
}
|
||||
m1 := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3,
|
||||
}
|
||||
|
||||
m2 := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 6,
|
||||
"d": 7,
|
||||
}
|
||||
m2 := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 6,
|
||||
"d": 7,
|
||||
}
|
||||
|
||||
m3 := map[string]int{
|
||||
"a": 1,
|
||||
"b": 9,
|
||||
"e": 9,
|
||||
}
|
||||
m3 := map[string]int{
|
||||
"a": 1,
|
||||
"b": 9,
|
||||
"e": 9,
|
||||
}
|
||||
|
||||
fmt.Println(maputil.Intersect(m1)) // map[string]int{"a": 1, "b": 2, "c": 3}
|
||||
result1 := maputil.Intersect(m1)
|
||||
result2 := maputil.Intersect(m1, m2)
|
||||
result3 := maputil.Intersect(m1, m2, m3)
|
||||
|
||||
fmt.Println(maputil.Intersect(m1, m2)) // map[string]int{"a": 1, "b": 2}
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
fmt.Println(maputil.Intersect(m1, m2, m3)) // map[string]int{"a": 1}
|
||||
// Output:
|
||||
// map[a:1 b:2 c:3]
|
||||
// map[a:1 b:2]
|
||||
// map[a:1]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="Keys">Keys</span>
|
||||
|
||||
<p>Returns a slice of the map's keys.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -171,6 +185,7 @@ func main() {
|
||||
```go
|
||||
func Keys[K comparable, V any](m map[K]V) []K
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -182,24 +197,26 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
m := map[int]string{
|
||||
1: "a",
|
||||
2: "a",
|
||||
3: "b",
|
||||
4: "c",
|
||||
5: "d",
|
||||
}
|
||||
m := map[int]string{
|
||||
1: "a",
|
||||
2: "a",
|
||||
3: "b",
|
||||
4: "c",
|
||||
5: "d",
|
||||
}
|
||||
|
||||
keys := maputil.Keys(m)
|
||||
sort.Ints(keys)
|
||||
fmt.Println(keys) // []int{1, 2, 3, 4, 5}
|
||||
keys := maputil.Keys(m)
|
||||
sort.Ints(keys)
|
||||
|
||||
fmt.Println(keys)
|
||||
|
||||
// Output:
|
||||
// [1 2 3 4 5]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="Merge">Merge</span>
|
||||
|
||||
<p>Merge maps, next key will overwrite previous key.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -207,6 +224,7 @@ func main() {
|
||||
```go
|
||||
func Merge[K comparable, V any](maps ...map[K]V) map[K]V
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -218,22 +236,26 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
m1 := map[int]string{
|
||||
1: "a",
|
||||
2: "b",
|
||||
}
|
||||
m2 := map[int]string{
|
||||
1: "1",
|
||||
3: "2",
|
||||
}
|
||||
fmt.Println(maputil.Merge(m1, m2)) // map[int]string{1:"1", 2:"b", 3:"2",}
|
||||
m1 := map[int]string{
|
||||
1: "a",
|
||||
2: "b",
|
||||
}
|
||||
m2 := map[int]string{
|
||||
1: "1",
|
||||
3: "2",
|
||||
}
|
||||
|
||||
result := maputil.Merge(m1, m2)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// map[1:c 2:b 3:d]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="Minus">Minus</span>
|
||||
|
||||
<p>Creates an map of whose key in mapA but not in mapB.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -241,6 +263,7 @@ func main() {
|
||||
```go
|
||||
func Minus[K comparable, V any](mapA, mapB map[K]V) map[K]V
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -252,25 +275,29 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
m1 := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3,
|
||||
}
|
||||
m1 := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3,
|
||||
}
|
||||
|
||||
m2 := map[string]int{
|
||||
"a": 11,
|
||||
"b": 22,
|
||||
"d": 33,
|
||||
}
|
||||
m2 := map[string]int{
|
||||
"a": 11,
|
||||
"b": 22,
|
||||
"d": 33,
|
||||
}
|
||||
|
||||
result := maputil.Minus(m1, m2)
|
||||
|
||||
fmt.Println(maputil.Minus(m1, m2)) //map[string]int{"c": 3}
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// map[c:3]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Values">Values</span>
|
||||
|
||||
<p>Returns a slice of the map's values.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -278,6 +305,7 @@ func main() {
|
||||
```go
|
||||
func Values[K comparable, V any](m map[K]V) []V
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -289,22 +317,26 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
m := map[int]string{
|
||||
1: "a",
|
||||
2: "a",
|
||||
3: "b",
|
||||
4: "c",
|
||||
5: "d",
|
||||
}
|
||||
m := map[int]string{
|
||||
1: "a",
|
||||
2: "a",
|
||||
3: "b",
|
||||
4: "c",
|
||||
5: "d",
|
||||
}
|
||||
|
||||
values := maputil.Values(m)
|
||||
sort.Strings(values)
|
||||
values := maputil.Values(m)
|
||||
sort.Strings(values)
|
||||
|
||||
fmt.Println(values) // []string{"a", "a", "b", "c", "d"}
|
||||
fmt.Println(values)
|
||||
|
||||
// Output:
|
||||
// [a a b c d]
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="IsDisjoint">IsDisjoint</span>
|
||||
|
||||
<p>Checks two maps are disjoint if they have no keys in common</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -312,6 +344,7 @@ func main() {
|
||||
```go
|
||||
func IsDisjoint[K comparable, V any](mapA, mapB map[K]V) bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -323,30 +356,28 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
m1 := map[int]string{
|
||||
1: "a",
|
||||
2: "a",
|
||||
3: "b",
|
||||
4: "c",
|
||||
5: "d",
|
||||
}
|
||||
m1 := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3,
|
||||
}
|
||||
|
||||
m2 := map[int]string{
|
||||
1: "a",
|
||||
2: "a",
|
||||
3: "b",
|
||||
4: "c",
|
||||
5: "d",
|
||||
}
|
||||
m2 := map[string]int{
|
||||
"d": 22,
|
||||
}
|
||||
|
||||
m3 := map[int]string{
|
||||
6: "a",
|
||||
}
|
||||
m3 := map[string]int{
|
||||
"a": 22,
|
||||
}
|
||||
|
||||
ok := maputil.IsDisjoint(m2, m1)
|
||||
fmt.Println(ok) // false
|
||||
result1 := maputil.IsDisjoint(m1, m2)
|
||||
result2 := maputil.IsDisjoint(m1, m3)
|
||||
|
||||
ok = maputil.IsDisjoint(m2, m3)
|
||||
fmt.Println(ok) // true
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// false
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
# Maputil
|
||||
maputil包包括一些操作map的函数。
|
||||
|
||||
maputil 包包括一些操作 map 的函数。
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/maputil/map.go](https://github.com/duke-git/lancet/blob/main/maputil/map.go)
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/maputil/map.go](https://github.com/duke-git/lancet/blob/main/maputil/map.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/maputil"
|
||||
@@ -20,22 +21,22 @@ import (
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录:
|
||||
- [ForEach](#ForEach)
|
||||
- [Filter](#Filter)
|
||||
- [Intersect](#Intersect)
|
||||
- [Keys](#Keys)
|
||||
- [Merge](#Merge)
|
||||
- [Minus](#Minus)
|
||||
- [Values](#Values)
|
||||
- [IsDisjoint](#IsDisjoint)
|
||||
|
||||
- [ForEach](#ForEach)
|
||||
- [Filter](#Filter)
|
||||
- [Intersect](#Intersect)
|
||||
- [Keys](#Keys)
|
||||
- [Merge](#Merge)
|
||||
- [Minus](#Minus)
|
||||
- [Values](#Values)
|
||||
- [IsDisjoint](#IsDisjoint)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## API文档:
|
||||
|
||||
|
||||
## API 文档:
|
||||
|
||||
### <span id="ForEach">ForEach</span>
|
||||
|
||||
<p>对map中的每对key和value执行iteratee函数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -43,7 +44,8 @@ import (
|
||||
```go
|
||||
func ForEach[K comparable, V any](m map[K]V, iteratee func(key K, value V))
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -54,26 +56,28 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
m := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3,
|
||||
"d": 4,
|
||||
}
|
||||
m := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3,
|
||||
"d": 4,
|
||||
}
|
||||
|
||||
var sum int
|
||||
var sum int
|
||||
|
||||
maputil.ForEach(m, func(_ string, value int) {
|
||||
sum += value
|
||||
})
|
||||
fmt.Println(sum) // 10
|
||||
maputil.ForEach(m, func(_ string, value int) {
|
||||
sum += value
|
||||
})
|
||||
|
||||
fmt.Println(sum)
|
||||
|
||||
// Output:
|
||||
// 10
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="Filter">Filter</span>
|
||||
|
||||
<p>迭代map中的每对key和value, 返回符合predicate函数的key, value</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -81,7 +85,8 @@ func main() {
|
||||
```go
|
||||
func Filter[K comparable, V any](m map[K]V, predicate func(key K, value V) bool) map[K]V
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -92,29 +97,32 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
m := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3,
|
||||
"d": 4,
|
||||
"e": 5,
|
||||
}
|
||||
isEven := func(_ string, value int) bool {
|
||||
return value%2 == 0
|
||||
}
|
||||
m := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3,
|
||||
"d": 4,
|
||||
"e": 5,
|
||||
}
|
||||
isEven := func(_ string, value int) bool {
|
||||
return value%2 == 0
|
||||
}
|
||||
|
||||
maputil.Filter(m, func(_ string, value int) {
|
||||
sum += value
|
||||
})
|
||||
res := maputil.Filter(m, isEven)
|
||||
fmt.Println(res) // map[string]int{"b": 2, "d": 4,}
|
||||
maputil.Filter(m, func(_ string, value int) {
|
||||
sum += value
|
||||
})
|
||||
|
||||
result := Filter(m, isEven)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// map[b:2 d:4]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="Intersect">Intersect</span>
|
||||
|
||||
<p>多个map的交集操作</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -122,7 +130,8 @@ func main() {
|
||||
```go
|
||||
func Intersect[K comparable, V any](maps ...map[K]V) map[K]V
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -133,37 +142,42 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
m1 := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3,
|
||||
}
|
||||
m1 := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3,
|
||||
}
|
||||
|
||||
m2 := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 6,
|
||||
"d": 7,
|
||||
}
|
||||
m2 := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 6,
|
||||
"d": 7,
|
||||
}
|
||||
|
||||
m3 := map[string]int{
|
||||
"a": 1,
|
||||
"b": 9,
|
||||
"e": 9,
|
||||
}
|
||||
m3 := map[string]int{
|
||||
"a": 1,
|
||||
"b": 9,
|
||||
"e": 9,
|
||||
}
|
||||
|
||||
fmt.Println(maputil.Intersect(m1)) // map[string]int{"a": 1, "b": 2, "c": 3}
|
||||
result1 := maputil.Intersect(m1)
|
||||
result2 := maputil.Intersect(m1, m2)
|
||||
result3 := maputil.Intersect(m1, m2, m3)
|
||||
|
||||
fmt.Println(maputil.Intersect(m1, m2)) // map[string]int{"a": 1, "b": 2}
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
fmt.Println(maputil.Intersect(m1, m2, m3)) // map[string]int{"a": 1}
|
||||
// Output:
|
||||
// map[a:1 b:2 c:3]
|
||||
// map[a:1 b:2]
|
||||
// map[a:1]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="Keys">Keys</span>
|
||||
|
||||
<p>返回map中所有key的切片</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -171,7 +185,8 @@ func main() {
|
||||
```go
|
||||
func Keys[K comparable, V any](m map[K]V) []K
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -182,24 +197,26 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
m := map[int]string{
|
||||
1: "a",
|
||||
2: "a",
|
||||
3: "b",
|
||||
4: "c",
|
||||
5: "d",
|
||||
}
|
||||
m := map[int]string{
|
||||
1: "a",
|
||||
2: "a",
|
||||
3: "b",
|
||||
4: "c",
|
||||
5: "d",
|
||||
}
|
||||
|
||||
keys := maputil.Keys(m)
|
||||
sort.Ints(keys)
|
||||
fmt.Println(keys) // []int{1, 2, 3, 4, 5}
|
||||
keys := maputil.Keys(m)
|
||||
sort.Ints(keys)
|
||||
|
||||
fmt.Println(keys)
|
||||
|
||||
// Output:
|
||||
// [1 2 3 4 5]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="Merge">Merge</span>
|
||||
|
||||
<p>合并多个maps, 相同的key会被后来的key覆盖</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -207,7 +224,8 @@ func main() {
|
||||
```go
|
||||
func Merge[K comparable, V any](maps ...map[K]V) map[K]V
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -218,21 +236,26 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
m1 := map[int]string{
|
||||
1: "a",
|
||||
2: "b",
|
||||
}
|
||||
m2 := map[int]string{
|
||||
1: "1",
|
||||
3: "2",
|
||||
}
|
||||
fmt.Println(maputil.Merge(m1, m2)) // map[int]string{1:"1", 2:"b", 3:"2",}
|
||||
m1 := map[int]string{
|
||||
1: "a",
|
||||
2: "b",
|
||||
}
|
||||
m2 := map[int]string{
|
||||
1: "1",
|
||||
3: "2",
|
||||
}
|
||||
|
||||
result := maputil.Merge(m1, m2)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// map[1:c 2:b 3:d]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Minus">Minus</span>
|
||||
|
||||
<p>返回一个map,其中的key存在于mapA,不存在于mapB.</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -240,7 +263,8 @@ func main() {
|
||||
```go
|
||||
func Minus[K comparable, V any](mapA, mapB map[K]V) map[K]V
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -251,25 +275,29 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
m1 := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3,
|
||||
}
|
||||
m1 := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3,
|
||||
}
|
||||
|
||||
m2 := map[string]int{
|
||||
"a": 11,
|
||||
"b": 22,
|
||||
"d": 33,
|
||||
}
|
||||
m2 := map[string]int{
|
||||
"a": 11,
|
||||
"b": 22,
|
||||
"d": 33,
|
||||
}
|
||||
|
||||
fmt.Println(maputil.Minus(m1, m2)) //map[string]int{"c": 3}
|
||||
result := maputil.Minus(m1, m2)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// map[c:3]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Values">Values</span>
|
||||
|
||||
<p>返回map中所有value的切片</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -277,7 +305,8 @@ func main() {
|
||||
```go
|
||||
func Values[K comparable, V any](m map[K]V) []V
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -288,23 +317,24 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
m := map[int]string{
|
||||
1: "a",
|
||||
2: "a",
|
||||
3: "b",
|
||||
4: "c",
|
||||
5: "d",
|
||||
}
|
||||
m := map[int]string{
|
||||
1: "a",
|
||||
2: "a",
|
||||
3: "b",
|
||||
4: "c",
|
||||
5: "d",
|
||||
}
|
||||
|
||||
values := maputil.Values(m)
|
||||
sort.Strings(values)
|
||||
values := maputil.Values(m)
|
||||
sort.Strings(values)
|
||||
|
||||
fmt.Println(values) // []string{"a", "a", "b", "c", "d"}
|
||||
// Output:
|
||||
// [a a b c d]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="IsDisjoint">IsDisjoint</span>
|
||||
|
||||
<p>验证两个map是否具有不同的key</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -312,7 +342,8 @@ func main() {
|
||||
```go
|
||||
func IsDisjoint[K comparable, V any](mapA, mapB map[K]V) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -323,30 +354,28 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
m1 := map[int]string{
|
||||
1: "a",
|
||||
2: "a",
|
||||
3: "b",
|
||||
4: "c",
|
||||
5: "d",
|
||||
}
|
||||
m1 := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3,
|
||||
}
|
||||
|
||||
m2 := map[int]string{
|
||||
1: "a",
|
||||
2: "a",
|
||||
3: "b",
|
||||
4: "c",
|
||||
5: "d",
|
||||
}
|
||||
m2 := map[string]int{
|
||||
"d": 22,
|
||||
}
|
||||
|
||||
m3 := map[int]string{
|
||||
6: "a",
|
||||
}
|
||||
m3 := map[string]int{
|
||||
"a": 22,
|
||||
}
|
||||
|
||||
ok := maputil.IsDisjoint(m2, m1)
|
||||
fmt.Println(ok) // false
|
||||
result1 := maputil.IsDisjoint(m1, m2)
|
||||
result2 := maputil.IsDisjoint(m1, m3)
|
||||
|
||||
ok = maputil.IsDisjoint(m2, m3)
|
||||
fmt.Println(ok) // true
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// false
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
297
docs/mathutil.md
297
docs/mathutil.md
@@ -1,16 +1,17 @@
|
||||
# Mathutil
|
||||
|
||||
Package mathutil implements some functions for math calculation.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go)
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
@@ -20,26 +21,26 @@ import (
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [Average](#Average)
|
||||
- [Exponent](#Exponent)
|
||||
- [Fibonacci](#Fibonacci)
|
||||
- [Factorial](#Factorial)
|
||||
- [Max](#Max)
|
||||
- [MaxBy](#MaxBy)
|
||||
- [Min](#Min)
|
||||
- [MinBy](#MaxBy)
|
||||
- [Percent](#Percent)
|
||||
- [RoundToFloat](#RoundToFloat)
|
||||
- [RoundToString](#RoundToString)
|
||||
- [TruncRound](#TruncRound)
|
||||
|
||||
- [Average](#Average)
|
||||
- [Exponent](#Exponent)
|
||||
- [Fibonacci](#Fibonacci)
|
||||
- [Factorial](#Factorial)
|
||||
- [Max](#Max)
|
||||
- [MaxBy](#MaxBy)
|
||||
- [Min](#Min)
|
||||
- [MinBy](#MaxBy)
|
||||
- [Percent](#Percent)
|
||||
- [RoundToFloat](#RoundToFloat)
|
||||
- [RoundToString](#RoundToString)
|
||||
- [TruncRound](#TruncRound)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
|
||||
### <span id="Average">Average</span>
|
||||
|
||||
<p>Return average value of numbers. Maybe call RoundToFloat to round result.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -47,6 +48,7 @@ import (
|
||||
```go
|
||||
func Average[T constraints.Integer | constraints.Float](numbers ...T) T
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -58,16 +60,22 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Average(0, 0)) //0
|
||||
fmt.Println(mathutil.Average(1, 1)) //1
|
||||
avg := mathutil.Average(1.2, 1.4) //1.2999999998
|
||||
roundAvg := mmathutil.RoundToFloat(avg, 1) // 1.3
|
||||
result1 := mathutil.Average(1, 2)
|
||||
|
||||
avg := mathutil.Average(1.2, 1.4)
|
||||
result2 := mathutil.RoundToFloat(avg, 1)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 1.3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Exponent">Exponent</span>
|
||||
|
||||
<p>Calculate x to the nth power.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -75,6 +83,7 @@ func main() {
|
||||
```go
|
||||
func Exponent(x, n int64) int64
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -86,15 +95,23 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Exponent(10, 0)) //1
|
||||
fmt.Println(mathutil.Exponent(10, 1)) //10
|
||||
fmt.Println(mathutil.Exponent(10, 2)) //100
|
||||
result1 := mathutil.Exponent(10, 0)
|
||||
result2 := mathutil.Exponent(10, 1)
|
||||
result3 := mathutil.Exponent(10, 2)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 10
|
||||
// 100
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Fibonacci">Fibonacci</span>
|
||||
|
||||
<p>Calculate the nth number of fibonacci sequence.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -102,6 +119,7 @@ func main() {
|
||||
```go
|
||||
func Fibonacci(first, second, n int) int
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -113,17 +131,23 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Fibonacci(1, 1, 1)) //1
|
||||
fmt.Println(mathutil.Fibonacci(1, 1, 2)) //1
|
||||
fmt.Println(mathutil.Fibonacci(1, 1, 3)) //2
|
||||
fmt.Println(mathutil.Fibonacci(1, 1, 4)) //3
|
||||
fmt.Println(mathutil.Fibonacci(1, 1, 5)) //5
|
||||
result1 := mathutil.Fibonacci(1, 1, 1)
|
||||
result2 := mathutil.Fibonacci(1, 1, 2)
|
||||
result3 := mathutil.Fibonacci(1, 1, 5)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 1
|
||||
// 5
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Factorial">Factorial</span>
|
||||
|
||||
<p>Calculate the factorial of x.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -131,6 +155,7 @@ func main() {
|
||||
```go
|
||||
func Factorial(x uint) uint
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -142,16 +167,23 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Factorial(0)) //1
|
||||
fmt.Println(mathutil.Factorial(1)) //1
|
||||
fmt.Println(mathutil.Factorial(2)) //2
|
||||
fmt.Println(mathutil.Factorial(3)) //6
|
||||
result1 := mathutil.Factorial(1)
|
||||
result2 := mathutil.Factorial(2)
|
||||
result3 := mathutil.Factorial(3)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
// 6
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Max">Max</span>
|
||||
|
||||
<p>Return max value of numbers.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -159,6 +191,7 @@ func main() {
|
||||
```go
|
||||
func Max[T constraints.Integer | constraints.Float](numbers ...T) T
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -170,23 +203,28 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Max(0, 0)) //0
|
||||
fmt.Println(mathutil.Max(1, 2, 3)) //3
|
||||
fmt.Println(mathutil.Max(1.2, 1.4, 1.1, 1.4)) //1.4
|
||||
result1 := mathutil.Max(1, 2, 3)
|
||||
result2 := mathutil.Max(1.2, 1.4, 1.1, 1.4)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// 3
|
||||
// 1.4
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="MaxBy">MaxBy</span>
|
||||
|
||||
<p>Return the maximum value of a slice using the given comparator function.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func MaxBy[T any](slice []T, comparator func(T, T) bool) T
|
||||
func MaxBy[T any](slice []T, comparator func(T, T) bool) T
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -198,26 +236,31 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := mathutil.MaxBy([]string{"a", "ab", "abc"}, func(v1, v2 string) bool {
|
||||
return len(v1) > len(v2)
|
||||
})
|
||||
fmt.Println(res1) //abc
|
||||
result1 := mathutil.MaxBy([]string{"a", "ab", "abc"}, func(v1, v2 string) bool {
|
||||
return len(v1) > len(v2)
|
||||
})
|
||||
|
||||
res2 := mathutil.MaxBy([]string{"abd", "abc", "ab"}, func(v1, v2 string) bool {
|
||||
return len(v1) > len(v2)
|
||||
})
|
||||
fmt.Println(res2) //abd
|
||||
result2 := mathutil.MaxBy([]string{"abd", "abc", "ab"}, func(v1, v2 string) bool {
|
||||
return len(v1) > len(v2)
|
||||
})
|
||||
|
||||
res3 := mathutil.MaxBy([]string{}, func(v1, v2 string) bool {
|
||||
return len(v1) > len(v2)
|
||||
})
|
||||
fmt.Println(res3) //“”
|
||||
result3 := mathutil.MaxBy([]string{}, func(v1, v2 string) bool {
|
||||
return len(v1) > len(v2)
|
||||
})
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// abc
|
||||
// abd
|
||||
//
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Min">Min</span>
|
||||
|
||||
<p>Return the minimum value of numbers.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -225,6 +268,7 @@ func main() {
|
||||
```go
|
||||
func Min[T constraints.Integer | constraints.Float](numbers ...T) T
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -236,22 +280,28 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Min(0, 0)) //0
|
||||
fmt.Println(mathutil.Min(1, 2, 3)) //1
|
||||
fmt.Println(mathutil.Min(1.2, 1.4, 1.1, 1.4)) //1.1
|
||||
result1 := mathutil.Min(1, 2, 3)
|
||||
result2 := mathutil.Min(1.2, 1.4, 1.1, 1.4)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 1.1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="MinBy">MinBy</span>
|
||||
|
||||
<p>Return the minimum value of a slice using the given comparator function.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func MinBy[T any](slice []T, comparator func(T, T) bool) T
|
||||
func MinBy[T any](slice []T, comparator func(T, T) bool) T
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -263,27 +313,31 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := mathutil.MinBy([]string{"a", "ab", "abc"}, func(v1, v2 string) bool {
|
||||
return len(v1) < len(v2)
|
||||
})
|
||||
fmt.Println(res1) //a
|
||||
result1 := mathutil.MinBy([]string{"a", "ab", "abc"}, func(v1, v2 string) bool {
|
||||
return len(v1) < len(v2)
|
||||
})
|
||||
|
||||
res2 := mathutil.MinBy([]string{"ab", "ac", "abc"}, func(v1, v2 string) bool {
|
||||
return len(v1) < len(v2)
|
||||
})
|
||||
fmt.Println(res2) //ab
|
||||
result2 := mathutil.MinBy([]string{"ab", "ac", "abc"}, func(v1, v2 string) bool {
|
||||
return len(v1) < len(v2)
|
||||
})
|
||||
|
||||
res3 := mathutil.MinBy([]string{}, func(v1, v2 string) bool {
|
||||
return len(v1) < len(v2)
|
||||
})
|
||||
fmt.Println(res3) //“”
|
||||
result3 := mathutil.MinBy([]string{}, func(v1, v2 string) bool {
|
||||
return len(v1) < len(v2)
|
||||
})
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// a
|
||||
// ab
|
||||
//
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="Percent">Percent</span>
|
||||
|
||||
<p>calculate the percentage of val to total, retain n decimal places.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -291,6 +345,7 @@ func main() {
|
||||
```go
|
||||
func Percent(val, total float64, n int) float64
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -302,14 +357,20 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Percent(1, 2, 2)) //0.5
|
||||
fmt.Println(mathutil.Percent(0.1, 0.3, 2)) //0.33
|
||||
result1 := mathutil.Percent(1, 2, 2)
|
||||
result2 := mathutil.Percent(0.1, 0.3, 2)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// 0.5
|
||||
// 0.33
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="RoundToFloat">RoundToFloat</span>
|
||||
|
||||
<p>Round float up to n decimal places.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -317,6 +378,7 @@ func main() {
|
||||
```go
|
||||
func RoundToFloat(x float64, n int) float64
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -328,18 +390,23 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.RoundToFloat(0, 0)) //0
|
||||
fmt.Println(mathutil.RoundToFloat(0, 1)) //0
|
||||
fmt.Println(mathutil.RoundToFloat(0.124, 2)) //0.12
|
||||
fmt.Println(mathutil.RoundToFloat(0.125, 2)) //0.13
|
||||
fmt.Println(mathutil.RoundToFloat(0.125, 3)) //0.125
|
||||
result1 := mathutil.RoundToFloat(0.124, 2)
|
||||
result2 := mathutil.RoundToFloat(0.125, 2)
|
||||
result3 := mathutil.RoundToFloat(0.125, 3)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// 0.12
|
||||
// 0.13
|
||||
// 0.125
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="RoundToString">RoundToString</span>
|
||||
|
||||
<p>Round float up to n decimal places. will return string.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -347,6 +414,7 @@ func main() {
|
||||
```go
|
||||
func RoundToString(x float64, n int) string
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -358,17 +426,23 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.RoundToString(0, 0)) //"0"
|
||||
fmt.Println(mathutil.RoundToString(0, 1)) //"0.0:
|
||||
fmt.Println(mathutil.RoundToString(0.124, 2)) //"0.12"
|
||||
fmt.Println(mathutil.RoundToString(0.125, 2)) //"0.13"
|
||||
fmt.Println(mathutil.RoundToString(0.125, 3)) //"0.125"
|
||||
result1 := mathutil.RoundToString(0.124, 2)
|
||||
result2 := mathutil.RoundToString(0.125, 2)
|
||||
result3 := mathutil.RoundToString(0.125, 3)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// 0.12
|
||||
// 0.13
|
||||
// 0.125
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="TruncRound">TruncRound</span>
|
||||
|
||||
<p>Round float off n decimal places.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -376,6 +450,7 @@ func main() {
|
||||
```go
|
||||
func TruncRound(x float64, n int) float64
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -387,13 +462,17 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.TruncRound(0, 0)) //0
|
||||
fmt.Println(mathutil.TruncRound(0, 1)) //0
|
||||
fmt.Println(mathutil.TruncRound(0.124, 2)) //0.12
|
||||
fmt.Println(mathutil.TruncRound(0.125, 2)) //0.12
|
||||
fmt.Println(mathutil.TruncRound(0.125, 3)) //0.125
|
||||
result1 := mathutil.TruncRound(0.124, 2)
|
||||
result2 := mathutil.TruncRound(0.125, 2)
|
||||
result3 := mathutil.TruncRound(0.125, 3)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// 0.12
|
||||
// 0.12
|
||||
// 0.125
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
# Mathutil
|
||||
mathutil包实现了一些数学计算的函数.
|
||||
|
||||
mathutil 包实现了一些数学计算的函数.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go)
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
@@ -20,25 +21,26 @@ import (
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录
|
||||
- [Average](#Average)
|
||||
- [Exponent](#Exponent)
|
||||
- [Fibonacci](#Fibonacci)
|
||||
- [Factorial](#Factorial)
|
||||
- [Max](#Max)
|
||||
- [MaxBy](#MaxBy)
|
||||
- [Min](#Min)
|
||||
- [MinBy](#MaxBy)
|
||||
- [Percent](#Percent)
|
||||
- [RoundToFloat](#RoundToFloat)
|
||||
- [RoundToString](#RoundToString)
|
||||
- [TruncRound](#TruncRound)
|
||||
|
||||
- [Average](#Average)
|
||||
- [Exponent](#Exponent)
|
||||
- [Fibonacci](#Fibonacci)
|
||||
- [Factorial](#Factorial)
|
||||
- [Max](#Max)
|
||||
- [MaxBy](#MaxBy)
|
||||
- [Min](#Min)
|
||||
- [MinBy](#MaxBy)
|
||||
- [Percent](#Percent)
|
||||
- [RoundToFloat](#RoundToFloat)
|
||||
- [RoundToString](#RoundToString)
|
||||
- [TruncRound](#TruncRound)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
### <span id="Average">Average</span>
|
||||
|
||||
<p>计算平均数. 可能需要对结果调用RoundToFloat方法四舍五入</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -46,7 +48,8 @@ import (
|
||||
```go
|
||||
func Average[T constraints.Integer | constraints.Float](numbers ...T) T
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -57,15 +60,22 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Average(0, 0)) //0
|
||||
fmt.Println(mathutil.Average(1, 1)) //1
|
||||
avg := mathutil.Average(1.2, 1.4) //1.2999999998
|
||||
roundAvg := mmathutil.RoundToFloat(avg, 1) // 1.3
|
||||
result1 := mathutil.Average(1, 2)
|
||||
|
||||
avg := mathutil.Average(1.2, 1.4)
|
||||
result2 := mathutil.RoundToFloat(avg, 1)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 1.3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="Exponent">Exponent</span>
|
||||
|
||||
<p>指数计算(x的n次方)</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -73,7 +83,8 @@ func main() {
|
||||
```go
|
||||
func Exponent(x, n int64) int64
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -84,15 +95,23 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Exponent(10, 0)) //1
|
||||
fmt.Println(mathutil.Exponent(10, 1)) //10
|
||||
fmt.Println(mathutil.Exponent(10, 2)) //100
|
||||
result1 := mathutil.Exponent(10, 0)
|
||||
result2 := mathutil.Exponent(10, 1)
|
||||
result3 := mathutil.Exponent(10, 2)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 10
|
||||
// 100
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Fibonacci">Fibonacci</span>
|
||||
|
||||
<p>计算斐波那契数列的第n个数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -100,7 +119,8 @@ func main() {
|
||||
```go
|
||||
func Fibonacci(first, second, n int) int
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -111,17 +131,23 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Fibonacci(1, 1, 1)) //1
|
||||
fmt.Println(mathutil.Fibonacci(1, 1, 2)) //1
|
||||
fmt.Println(mathutil.Fibonacci(1, 1, 3)) //2
|
||||
fmt.Println(mathutil.Fibonacci(1, 1, 4)) //3
|
||||
fmt.Println(mathutil.Fibonacci(1, 1, 5)) //5
|
||||
result1 := mathutil.Fibonacci(1, 1, 1)
|
||||
result2 := mathutil.Fibonacci(1, 1, 2)
|
||||
result3 := mathutil.Fibonacci(1, 1, 5)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 1
|
||||
// 5
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Factorial">Factorial</span>
|
||||
|
||||
<p>计算阶乘</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -129,7 +155,8 @@ func main() {
|
||||
```go
|
||||
func Factorial(x uint) uint
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -140,15 +167,23 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Factorial(0)) //1
|
||||
fmt.Println(mathutil.Factorial(1)) //1
|
||||
fmt.Println(mathutil.Factorial(2)) //2
|
||||
fmt.Println(mathutil.Factorial(3)) //6
|
||||
result1 := mathutil.Factorial(1)
|
||||
result2 := mathutil.Factorial(2)
|
||||
result3 := mathutil.Factorial(3)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
// 6
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="Max">Max</span>
|
||||
|
||||
<p>返回参数中的最大数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -156,7 +191,8 @@ func main() {
|
||||
```go
|
||||
func Max[T constraints.Integer | constraints.Float](numbers ...T) T
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -167,23 +203,29 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Max(0, 0)) //0
|
||||
fmt.Println(mathutil.Max(1, 2, 3)) //3
|
||||
fmt.Println(mathutil.Max(1.2, 1.4, 1.1, 1.4)) //1.4
|
||||
result1 := mathutil.Max(1, 2, 3)
|
||||
result2 := mathutil.Max(1.2, 1.4, 1.1, 1.4)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// 3
|
||||
// 1.4
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="MaxBy">MaxBy</span>
|
||||
|
||||
<p>使用给定的比较器函数返回切片的最大值</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func MaxBy[T any](slice []T, comparator func(T, T) bool) T
|
||||
func MaxBy[T any](slice []T, comparator func(T, T) bool) T
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -194,27 +236,31 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := mathutil.MaxBy([]string{"a", "ab", "abc"}, func(v1, v2 string) bool {
|
||||
return len(v1) > len(v2)
|
||||
})
|
||||
fmt.Println(res1) //abc
|
||||
result1 := mathutil.MaxBy([]string{"a", "ab", "abc"}, func(v1, v2 string) bool {
|
||||
return len(v1) > len(v2)
|
||||
})
|
||||
|
||||
res2 := mathutil.MaxBy([]string{"abd", "abc", "ab"}, func(v1, v2 string) bool {
|
||||
return len(v1) > len(v2)
|
||||
})
|
||||
fmt.Println(res2) //abd
|
||||
result2 := mathutil.MaxBy([]string{"abd", "abc", "ab"}, func(v1, v2 string) bool {
|
||||
return len(v1) > len(v2)
|
||||
})
|
||||
|
||||
res3 := mathutil.MaxBy([]string{}, func(v1, v2 string) bool {
|
||||
return len(v1) > len(v2)
|
||||
})
|
||||
fmt.Println(res3) //“”
|
||||
result3 := mathutil.MaxBy([]string{}, func(v1, v2 string) bool {
|
||||
return len(v1) > len(v2)
|
||||
})
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// abc
|
||||
// abd
|
||||
//
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="Min">Min</span>
|
||||
|
||||
<p>返回参数中的最小数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -222,7 +268,8 @@ func main() {
|
||||
```go
|
||||
func Min[T constraints.Integer | constraints.Float](numbers ...T) T
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -233,23 +280,29 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Min(0, 0)) //0
|
||||
fmt.Println(mathutil.Min(1, 2, 3)) //1
|
||||
fmt.Println(mathutil.Min(1.2, 1.4, 1.1, 1.4)) //1.1
|
||||
result1 := mathutil.Min(1, 2, 3)
|
||||
result2 := mathutil.Min(1.2, 1.4, 1.1, 1.4)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 1.1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="MinBy">MinBy</span>
|
||||
|
||||
<p>使用给定的比较器函数返回切片的最小值</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func MinBy[T any](slice []T, comparator func(T, T) bool) T
|
||||
func MinBy[T any](slice []T, comparator func(T, T) bool) T
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -260,27 +313,31 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := mathutil.MinBy([]string{"a", "ab", "abc"}, func(v1, v2 string) bool {
|
||||
return len(v1) < len(v2)
|
||||
})
|
||||
fmt.Println(res1) //a
|
||||
result1 := mathutil.MinBy([]string{"a", "ab", "abc"}, func(v1, v2 string) bool {
|
||||
return len(v1) < len(v2)
|
||||
})
|
||||
|
||||
res2 := mathutil.MinBy([]string{"ab", "ac", "abc"}, func(v1, v2 string) bool {
|
||||
return len(v1) < len(v2)
|
||||
})
|
||||
fmt.Println(res2) //ab
|
||||
result2 := mathutil.MinBy([]string{"ab", "ac", "abc"}, func(v1, v2 string) bool {
|
||||
return len(v1) < len(v2)
|
||||
})
|
||||
|
||||
res3 := mathutil.MinBy([]string{}, func(v1, v2 string) bool {
|
||||
return len(v1) < len(v2)
|
||||
})
|
||||
fmt.Println(res3) //“”
|
||||
result3 := mathutil.MinBy([]string{}, func(v1, v2 string) bool {
|
||||
return len(v1) < len(v2)
|
||||
})
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// a
|
||||
// ab
|
||||
//
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="Percent">Percent</span>
|
||||
|
||||
<p>计算百分比,保留n位小数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -288,7 +345,8 @@ func main() {
|
||||
```go
|
||||
func Percent(val, total float64, n int) float64
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -299,14 +357,20 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Percent(1, 2, 2)) //0.5
|
||||
fmt.Println(mathutil.Percent(0.1, 0.3, 2)) //0.33
|
||||
result1 := mathutil.Percent(1, 2, 2)
|
||||
result2 := mathutil.Percent(0.1, 0.3, 2)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// 0.5
|
||||
// 0.33
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="RoundToFloat">RoundToFloat</span>
|
||||
|
||||
<p>四舍五入,保留n位小数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -314,7 +378,8 @@ func main() {
|
||||
```go
|
||||
func RoundToFloat(x float64, n int) float64
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -325,18 +390,23 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.RoundToFloat(0, 0)) //0
|
||||
fmt.Println(mathutil.RoundToFloat(0, 1)) //0
|
||||
fmt.Println(mathutil.RoundToFloat(0.124, 2)) //0.12
|
||||
fmt.Println(mathutil.RoundToFloat(0.125, 2)) //0.13
|
||||
fmt.Println(mathutil.RoundToFloat(0.125, 3)) //0.125
|
||||
result1 := mathutil.RoundToFloat(0.124, 2)
|
||||
result2 := mathutil.RoundToFloat(0.125, 2)
|
||||
result3 := mathutil.RoundToFloat(0.125, 3)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// 0.12
|
||||
// 0.13
|
||||
// 0.125
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="RoundToString">RoundToString</span>
|
||||
|
||||
<p>四舍五入,保留n位小数,返回字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -344,7 +414,8 @@ func main() {
|
||||
```go
|
||||
func RoundToString(x float64, n int) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -355,17 +426,23 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.RoundToString(0, 0)) //"0"
|
||||
fmt.Println(mathutil.RoundToString(0, 1)) //"0.0:
|
||||
fmt.Println(mathutil.RoundToString(0.124, 2)) //"0.12"
|
||||
fmt.Println(mathutil.RoundToString(0.125, 2)) //"0.13"
|
||||
fmt.Println(mathutil.RoundToString(0.125, 3)) //"0.125"
|
||||
result1 := mathutil.RoundToString(0.124, 2)
|
||||
result2 := mathutil.RoundToString(0.125, 2)
|
||||
result3 := mathutil.RoundToString(0.125, 3)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// 0.12
|
||||
// 0.13
|
||||
// 0.125
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="TruncRound">TruncRound</span>
|
||||
|
||||
<p>截短n位小数(不进行四舍五入)</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -373,7 +450,8 @@ func main() {
|
||||
```go
|
||||
func TruncRound(x float64, n int) float64
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -384,13 +462,17 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.TruncRound(0, 0)) //0
|
||||
fmt.Println(mathutil.TruncRound(0, 1)) //0
|
||||
fmt.Println(mathutil.TruncRound(0.124, 2)) //0.12
|
||||
fmt.Println(mathutil.TruncRound(0.125, 2)) //0.12
|
||||
fmt.Println(mathutil.TruncRound(0.125, 3)) //0.125
|
||||
result1 := mathutil.TruncRound(0.124, 2)
|
||||
result2 := mathutil.TruncRound(0.125, 2)
|
||||
result3 := mathutil.TruncRound(0.125, 3)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// 0.12
|
||||
// 0.12
|
||||
// 0.125
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
681
docs/netutil.md
681
docs/netutil.md
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -56,8 +56,8 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
randBytes := random.RandBytes(4)
|
||||
fmt.Println(randBytes)
|
||||
randBytes := random.RandBytes(4)
|
||||
fmt.Println(randBytes)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -82,8 +82,8 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
rInt := random.RandInt(1, 10)
|
||||
fmt.Println(rInt)
|
||||
rInt := random.RandInt(1, 10)
|
||||
fmt.Println(rInt)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -108,8 +108,8 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
randStr := random.RandString(6)
|
||||
fmt.Println(randStr) //pGWsze
|
||||
randStr := random.RandString(6)
|
||||
fmt.Println(randStr) //pGWsze
|
||||
}
|
||||
```
|
||||
|
||||
@@ -134,8 +134,8 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
randStr := random.RandString(6)
|
||||
fmt.Println(randStr) //PACWGF
|
||||
randStr := random.RandString(6)
|
||||
fmt.Println(randStr) //PACWGF
|
||||
}
|
||||
```
|
||||
|
||||
@@ -160,8 +160,8 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
randStr := random.RandLower(6)
|
||||
fmt.Println(randStr) //siqbew
|
||||
randStr := random.RandLower(6)
|
||||
fmt.Println(randStr) //siqbew
|
||||
}
|
||||
```
|
||||
|
||||
@@ -186,8 +186,8 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
randStr := random.RandNumeral(6)
|
||||
fmt.Println(randStr) //035172
|
||||
randStr := random.RandNumeral(6)
|
||||
fmt.Println(randStr) //035172
|
||||
}
|
||||
```
|
||||
|
||||
@@ -212,8 +212,8 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
randStr := random.RandNumeralOrLetter(6)
|
||||
fmt.Println(randStr) //0aW7cQ
|
||||
randStr := random.RandNumeralOrLetter(6)
|
||||
fmt.Println(randStr) //0aW7cQ
|
||||
}
|
||||
```
|
||||
|
||||
@@ -238,10 +238,10 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
uuid, err := random.UUIdV4()
|
||||
uuid, err := random.UUIdV4()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
fmt.Println(uuid)
|
||||
fmt.Println(uuid)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -45,7 +45,7 @@ import (
|
||||
func RandBytes(length int) []byte
|
||||
```
|
||||
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -56,8 +56,8 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
randBytes := random.RandBytes(4)
|
||||
fmt.Println(randBytes)
|
||||
randBytes := random.RandBytes(4)
|
||||
fmt.Println(randBytes)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -71,7 +71,7 @@ func main() {
|
||||
func RandInt(min, max int) int
|
||||
```
|
||||
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -82,8 +82,8 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
rInt := random.RandInt(1, 10)
|
||||
fmt.Println(rInt)
|
||||
rInt := random.RandInt(1, 10)
|
||||
fmt.Println(rInt)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -97,7 +97,7 @@ func main() {
|
||||
func RandString(length int) string
|
||||
```
|
||||
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -108,8 +108,8 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
randStr := random.RandString(6)
|
||||
fmt.Println(randStr) //pGWsze
|
||||
randStr := random.RandString(6)
|
||||
fmt.Println(randStr) //pGWsze
|
||||
}
|
||||
```
|
||||
|
||||
@@ -123,7 +123,7 @@ func main() {
|
||||
func RandUpper(length int) string
|
||||
```
|
||||
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -134,8 +134,8 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
randStr := random.RandString(6)
|
||||
fmt.Println(randStr) //PACWGF
|
||||
randStr := random.RandString(6)
|
||||
fmt.Println(randStr) //PACWGF
|
||||
}
|
||||
```
|
||||
|
||||
@@ -149,7 +149,7 @@ func main() {
|
||||
func RandLower(length int) string
|
||||
```
|
||||
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -160,8 +160,8 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
randStr := random.RandLower(6)
|
||||
fmt.Println(randStr) //siqbew
|
||||
randStr := random.RandLower(6)
|
||||
fmt.Println(randStr) //siqbew
|
||||
}
|
||||
```
|
||||
|
||||
@@ -175,7 +175,7 @@ func main() {
|
||||
func RandNumeral(length int) string
|
||||
```
|
||||
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -186,8 +186,8 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
randStr := random.RandNumeral(6)
|
||||
fmt.Println(randStr) //035172
|
||||
randStr := random.RandNumeral(6)
|
||||
fmt.Println(randStr) //035172
|
||||
}
|
||||
```
|
||||
|
||||
@@ -201,7 +201,7 @@ func main() {
|
||||
func RandNumeralOrLetter(length int) string
|
||||
```
|
||||
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -212,8 +212,8 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
randStr := random.RandNumeralOrLetter(6)
|
||||
fmt.Println(randStr) //0aW7cQ
|
||||
randStr := random.RandNumeralOrLetter(6)
|
||||
fmt.Println(randStr) //0aW7cQ
|
||||
}
|
||||
```
|
||||
|
||||
@@ -227,7 +227,7 @@ func main() {
|
||||
func UUIdV4() (string, error)
|
||||
```
|
||||
|
||||
<b>例子:</b>
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -238,10 +238,10 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
uuid, err := random.UUIdV4()
|
||||
uuid, err := random.UUIdV4()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
fmt.Println(uuid)
|
||||
fmt.Println(uuid)
|
||||
}
|
||||
```
|
||||
|
||||
192
docs/retry.md
192
docs/retry.md
@@ -1,16 +1,17 @@
|
||||
# Retry
|
||||
|
||||
Package retry is for executing a function repeatedly until it was successful or canceled by the context.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/retry/retry.go](https://github.com/duke-git/lancet/blob/main/retry/retry.go)
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/retry/retry.go](https://github.com/duke-git/lancet/blob/main/retry/retry.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Usage:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/retry"
|
||||
@@ -20,18 +21,19 @@ import (
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [Context](#Context)
|
||||
- [Retry](#Retry)
|
||||
- [RetryFunc](#RetryFunc)
|
||||
- [RetryDuration](#RetryDuration)
|
||||
- [RetryTimes](#RetryTimes)
|
||||
|
||||
- [Context](#Context)
|
||||
- [Retry](#Retry)
|
||||
- [RetryFunc](#RetryFunc)
|
||||
- [RetryDuration](#RetryDuration)
|
||||
- [RetryTimes](#RetryTimes)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
### <span id="Context">Context</span>
|
||||
|
||||
<p>Set retry context config, can cancel the retry with context.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -39,43 +41,46 @@ import (
|
||||
```go
|
||||
func Context(ctx context.Context)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/retry"
|
||||
"time"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/retry"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, cancel := context.WithCancel(context.TODO())
|
||||
var number int
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number > 3 {
|
||||
cancel()
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
ctx, cancel := context.WithCancel(context.TODO())
|
||||
|
||||
err := retry.Retry(increaseNumber,
|
||||
retry.RetryDuration(time.Microsecond*50),
|
||||
retry.Context(ctx),
|
||||
)
|
||||
number := 0
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number > 3 {
|
||||
cancel()
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err) //retry is cancelled
|
||||
}
|
||||
duration := retry.RetryDuration(time.Microsecond*50)
|
||||
|
||||
retry.Retry(increaseNumber,
|
||||
duration,
|
||||
retry.Context(ctx),
|
||||
)
|
||||
|
||||
fmt.Println(number)
|
||||
|
||||
// Output:
|
||||
// 4
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="RetryFunc">RetryFunc</span>
|
||||
|
||||
<p>Function that retry executes.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -83,6 +88,7 @@ func main() {
|
||||
```go
|
||||
type RetryFunc func() error
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -96,28 +102,31 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
var number int
|
||||
number := 0
|
||||
var increaseNumber retry.RetryFunc = func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
duration := retry.RetryDuration(time.Microsecond*50)
|
||||
|
||||
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
||||
err := retry.Retry(increaseNumber, duration)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(number) //3
|
||||
fmt.Println(number)
|
||||
|
||||
// Output:
|
||||
// 3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="RetryTimes">RetryTimes</span>
|
||||
|
||||
<p>Set times of retry. Default times is 5.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -125,6 +134,7 @@ func main() {
|
||||
```go
|
||||
func RetryTimes(n uint)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -138,26 +148,28 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
var number int
|
||||
number := 0
|
||||
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
err := retry.Retry(increaseNumber, retry.RetryTimes(2))
|
||||
err := retry.Retry(increaseNumber, retry.RetryTimes(2))
|
||||
if err != nil {
|
||||
log.Fatal(err) //2022/02/01 18:42:25 function main.main.func1 run failed after 2 times retry exit status 1
|
||||
}
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// function main.main.func1 run failed after 2 times retry
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="RetryDuration">RetryDuration</span>
|
||||
|
||||
<p>Set duration of retries. Default duration is 3 second.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -165,6 +177,7 @@ func main() {
|
||||
```go
|
||||
func RetryDuration(d time.Duration)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -178,26 +191,31 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
var number int
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
number := 0
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
||||
duration := retry.RetryDuration(time.Microsecond*50)
|
||||
|
||||
err := retry.Retry(increaseNumber, duration)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(number) //3
|
||||
fmt.Println(number)
|
||||
|
||||
// Output:
|
||||
// 3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="Retry">Retry</span>
|
||||
|
||||
<p>Executes the retryFunc repeatedly until it was successful or canceled by the context.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -205,6 +223,7 @@ func main() {
|
||||
```go
|
||||
func Retry(retryFunc RetryFunc, opts ...Option) error
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -218,20 +237,25 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
var number int
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
number := 0
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
||||
duration := retry.RetryDuration(time.Microsecond*50)
|
||||
|
||||
err := retry.Retry(increaseNumber, duration)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(number) //3
|
||||
fmt.Println(number)
|
||||
|
||||
// Output:
|
||||
// 3
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
# Retry
|
||||
retry重试执行函数直到函数运行成功或被context cancel。
|
||||
|
||||
retry 重试执行函数直到函数运行成功或被 context cancel。
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/retry/retry.go](https://github.com/duke-git/lancet/blob/main/retry/retry.go)
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/retry/retry.go](https://github.com/duke-git/lancet/blob/main/retry/retry.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/retry"
|
||||
@@ -20,20 +21,19 @@ import (
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录
|
||||
- [Context](#Context)
|
||||
- [Retry](#Retry)
|
||||
- [RetryFunc](#RetryFunc)
|
||||
- [RetryDuration](#RetryDuration)
|
||||
- [RetryTimes](#RetryTimes)
|
||||
|
||||
- [Context](#Context)
|
||||
- [Retry](#Retry)
|
||||
- [RetryFunc](#RetryFunc)
|
||||
- [RetryDuration](#RetryDuration)
|
||||
- [RetryTimes](#RetryTimes)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
|
||||
## Document文档
|
||||
|
||||
## Document 文档
|
||||
|
||||
### <span id="Context">Context</span>
|
||||
|
||||
<p>设置重试context参数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -41,43 +41,46 @@ import (
|
||||
```go
|
||||
func Context(ctx context.Context)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"lancet-demo/retry"
|
||||
"time"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"lancet-demo/retry"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, cancel := context.WithCancel(context.TODO())
|
||||
var number int
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number > 3 {
|
||||
cancel()
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
ctx, cancel := context.WithCancel(context.TODO())
|
||||
|
||||
err := retry.Retry(increaseNumber,
|
||||
retry.RetryDuration(time.Microsecond*50),
|
||||
retry.Context(ctx),
|
||||
)
|
||||
number := 0
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number > 3 {
|
||||
cancel()
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err) //retry is cancelled
|
||||
}
|
||||
duration := retry.RetryDuration(time.Microsecond*50)
|
||||
|
||||
retry.Retry(increaseNumber,
|
||||
duration,
|
||||
retry.Context(ctx),
|
||||
)
|
||||
|
||||
fmt.Println(number)
|
||||
|
||||
// Output:
|
||||
// 4
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="RetryFunc">RetryFunc</span>
|
||||
|
||||
<p>被重试执行的函数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -85,7 +88,8 @@ func main() {
|
||||
```go
|
||||
type RetryFunc func() error
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -98,27 +102,31 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
var number int
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
number := 0
|
||||
var increaseNumber retry.RetryFunc = func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
||||
duration := retry.RetryDuration(time.Microsecond*50)
|
||||
|
||||
err := retry.Retry(increaseNumber, duration)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(number) //3
|
||||
fmt.Println(number)
|
||||
|
||||
// Output:
|
||||
// 3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="RetryTimes">RetryTimes</span>
|
||||
|
||||
<p>设置重试次数,默认5</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -126,7 +134,8 @@ func main() {
|
||||
```go
|
||||
func RetryTimes(n uint)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -139,25 +148,28 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
var number int
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
number := 0
|
||||
|
||||
err := retry.Retry(increaseNumber, retry.RetryTimes(2))
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
err := retry.Retry(increaseNumber, retry.RetryTimes(2))
|
||||
if err != nil {
|
||||
log.Fatal(err) //2022/02/01 18:42:25 function main.main.func1 run failed after 2 times retry exit status 1
|
||||
}
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// function main.main.func1 run failed after 2 times retry
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="RetryDuration">RetryDuration</span>
|
||||
|
||||
<p>设置重试间隔时间,默认3秒</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -165,7 +177,8 @@ func main() {
|
||||
```go
|
||||
func RetryDuration(d time.Duration)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -178,26 +191,31 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
var number int
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
number := 0
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
||||
duration := retry.RetryDuration(time.Microsecond*50)
|
||||
|
||||
err := retry.Retry(increaseNumber, duration)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(number) //3
|
||||
fmt.Println(number)
|
||||
|
||||
// Output:
|
||||
// 3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="Retry">Retry</span>
|
||||
|
||||
<p>重试执行函数retryFunc,直到函数运行成功,或被context停止</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -205,7 +223,8 @@ func main() {
|
||||
```go
|
||||
func Retry(retryFunc RetryFunc, opts ...Option) error
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -218,20 +237,25 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
var number int
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
number := 0
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
||||
duration := retry.RetryDuration(time.Microsecond*50)
|
||||
|
||||
err := retry.Retry(increaseNumber, duration)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(number) //3
|
||||
fmt.Println(number)
|
||||
|
||||
// Output:
|
||||
// 3
|
||||
}
|
||||
```
|
||||
|
||||
1049
docs/slice.md
1049
docs/slice.md
File diff suppressed because it is too large
Load Diff
1163
docs/slice_zh-CN.md
1163
docs/slice_zh-CN.md
File diff suppressed because it is too large
Load Diff
708
docs/strutil.md
708
docs/strutil.md
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
205
docs/system.md
205
docs/system.md
@@ -1,16 +1,17 @@
|
||||
# System
|
||||
|
||||
Package system contains some functions about os, runtime, shell command.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/system/os.go](https://github.com/duke-git/lancet/blob/main/system/os.go)
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/system/os.go](https://github.com/duke-git/lancet/blob/main/system/os.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Usage:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
@@ -20,23 +21,23 @@ import (
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [IsWindows](#IsWindows)
|
||||
- [IsLinux](#IsLinux)
|
||||
- [IsMac](#IsMac)
|
||||
- [GetOsEnv](#GetOsEnv)
|
||||
- [SetOsEnv](#SetOsEnv)
|
||||
- [RemoveOsEnv](#RemoveOsEnv)
|
||||
- [CompareOsEnv](#CompareOsEnv)
|
||||
- [ExecCommand](#ExecCommand)
|
||||
- [GetOsBits](#GetOsBits)
|
||||
|
||||
|
||||
- [IsWindows](#IsWindows)
|
||||
- [IsLinux](#IsLinux)
|
||||
- [IsMac](#IsMac)
|
||||
- [GetOsEnv](#GetOsEnv)
|
||||
- [SetOsEnv](#SetOsEnv)
|
||||
- [RemoveOsEnv](#RemoveOsEnv)
|
||||
- [CompareOsEnv](#CompareOsEnv)
|
||||
- [ExecCommand](#ExecCommand)
|
||||
- [GetOsBits](#GetOsBits)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
### <span id="IsWindows">IsWindows</span>
|
||||
|
||||
<p>Check if current os is windows.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -44,24 +45,23 @@ import (
|
||||
```go
|
||||
func IsWindows() bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
isOsWindows := system.IsWindows()
|
||||
fmt.Println(isOsWindows)
|
||||
isOsWindows := system.IsWindows()
|
||||
fmt.Println(isOsWindows)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsLinux">IsLinux</span>
|
||||
|
||||
<p>Check if current os is linux.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -69,23 +69,23 @@ func main() {
|
||||
```go
|
||||
func IsLinux() bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
isOsLinux := system.IsLinux()
|
||||
fmt.Println(isOsLinux)
|
||||
isOsLinux := system.IsLinux()
|
||||
fmt.Println(isOsLinux)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="IsMac">IsMac</span>
|
||||
|
||||
<p>Check if current os is macos.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -93,23 +93,23 @@ func main() {
|
||||
```go
|
||||
func IsMac() bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
isOsMac := system.IsMac()
|
||||
fmt.Println(isOsMac)
|
||||
isOsMac := system.IsMac()
|
||||
fmt.Println(isOsMac)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="GetOsEnv">GetOsEnv</span>
|
||||
|
||||
<p>Gets the value of the environment variable named by the key.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -117,23 +117,29 @@ func main() {
|
||||
```go
|
||||
func GetOsEnv(key string) string
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fooEnv := system.GetOsEnv("foo")
|
||||
fmt.Println(fooEnv)
|
||||
err := system.SetOsEnv("foo", "abc")
|
||||
result := system.GetOsEnv("foo")
|
||||
|
||||
fmt.Println(err)
|
||||
fmt.Println(result)
|
||||
// Output:
|
||||
// <nil>
|
||||
// abc
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="SetOsEnv">SetOsEnv</span>
|
||||
|
||||
<p>Sets the value of the environment variable named by the key.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -141,24 +147,29 @@ func main() {
|
||||
```go
|
||||
func SetOsEnv(key, value string) error
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := system.SetOsEnv("foo", "foo_value")
|
||||
fmt.Println(err)
|
||||
err := system.SetOsEnv("foo", "abc")
|
||||
result := system.GetOsEnv("foo")
|
||||
|
||||
fmt.Println(err)
|
||||
fmt.Println(result)
|
||||
// Output:
|
||||
// <nil>
|
||||
// abc
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="RemoveOsEnv">RemoveOsEnv</span>
|
||||
|
||||
<p>Remove a single environment variable.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -166,25 +177,37 @@ func main() {
|
||||
```go
|
||||
func RemoveOsEnv(key string) error
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := system.RemoveOsEnv("foo")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
err1 := system.SetOsEnv("foo", "abc")
|
||||
result1 := GetOsEnv("foo")
|
||||
|
||||
err2 := system.RemoveOsEnv("foo")
|
||||
result2 := GetOsEnv("foo")
|
||||
|
||||
fmt.Println(err1)
|
||||
fmt.Println(err2)
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// <nil>
|
||||
// <nil>
|
||||
// abc
|
||||
//
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="CompareOsEnv">CompareOsEnv</span>
|
||||
|
||||
<p>Get env named by the key and compare it with comparedEnv.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -192,25 +215,32 @@ func main() {
|
||||
```go
|
||||
func CompareOsEnv(key, comparedEnv string) bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
system.SetOsEnv("foo", "foo_value")
|
||||
res := system.CompareOsEnv("foo", "foo_value")
|
||||
fmt.Println(res) //true
|
||||
err := system.SetOsEnv("foo", "abc")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
result := system.CompareOsEnv("foo", "abc")
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="ExecCommand">CompareOsEnv</span>
|
||||
|
||||
<p>Execute shell command, return the stdout and stderr string of command, and error if error occur. param `command` is a complete command string, like, ls -a (linux), dir(windows), ping 127.0.0.1. In linux, use /bin/bash -c to execute command, In windows, use powershell.exe to execute command.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -218,40 +248,39 @@ func main() {
|
||||
```go
|
||||
func ExecCommand(command string) (stdout, stderr string, err error)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// linux or mac
|
||||
stdout, stderr, err := system.ExecCommand("ls")
|
||||
fmt.Println("std out: ", stdout)
|
||||
fmt.Println("std err: ", stderr)
|
||||
assert.Equal("", stderr)
|
||||
// linux or mac
|
||||
stdout, stderr, err := system.ExecCommand("ls")
|
||||
fmt.Println("std out: ", stdout)
|
||||
fmt.Println("std err: ", stderr)
|
||||
assert.Equal("", stderr)
|
||||
|
||||
// windows
|
||||
stdout, stderr, err = system.ExecCommand("dir")
|
||||
fmt.Println("std out: ", stdout)
|
||||
fmt.Println("std err: ", stderr)
|
||||
// windows
|
||||
stdout, stderr, err = system.ExecCommand("dir")
|
||||
fmt.Println("std out: ", stdout)
|
||||
fmt.Println("std err: ", stderr)
|
||||
|
||||
// error command
|
||||
stdout, stderr, err = system.ExecCommand("abc")
|
||||
fmt.Println("std out: ", stdout)
|
||||
fmt.Println("std err: ", stderr)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
// error command
|
||||
stdout, stderr, err = system.ExecCommand("abc")
|
||||
fmt.Println("std out: ", stdout)
|
||||
fmt.Println("std err: ", stderr)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="GetOsBits">GetOsBits</span>
|
||||
|
||||
<p>Get current os bits, 32bit or 64bit. return 32 or 64</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -259,19 +288,17 @@ func main() {
|
||||
```go
|
||||
func GetOsBits() int
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
osBit := system.GetOsBits()
|
||||
fmt.Println(osBit)
|
||||
osBit := system.GetOsBits()
|
||||
fmt.Println(osBit) // 32 or 64
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
# System
|
||||
system包含os, runtime, shell command相关函数。
|
||||
|
||||
system 包含 os, runtime, shell command 相关函数。
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/system/os.go](https://github.com/duke-git/lancet/blob/main/system/os.go)
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/system/os.go](https://github.com/duke-git/lancet/blob/main/system/os.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
@@ -20,23 +21,23 @@ import (
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录
|
||||
- [IsWindows](#IsWindows)
|
||||
- [IsLinux](#IsLinux)
|
||||
- [IsMac](#IsMac)
|
||||
- [GetOsEnv](#GetOsEnv)
|
||||
- [SetOsEnv](#SetOsEnv)
|
||||
- [RemoveOsEnv](#RemoveOsEnv)
|
||||
- [CompareOsEnv](#CompareOsEnv)
|
||||
- [ExecCommand](#ExecCommand)
|
||||
- [GetOsBits](#GetOsBits)
|
||||
|
||||
|
||||
- [IsWindows](#IsWindows)
|
||||
- [IsLinux](#IsLinux)
|
||||
- [IsMac](#IsMac)
|
||||
- [GetOsEnv](#GetOsEnv)
|
||||
- [SetOsEnv](#SetOsEnv)
|
||||
- [RemoveOsEnv](#RemoveOsEnv)
|
||||
- [CompareOsEnv](#CompareOsEnv)
|
||||
- [ExecCommand](#ExecCommand)
|
||||
- [GetOsBits](#GetOsBits)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation文档
|
||||
|
||||
## Documentation 文档
|
||||
|
||||
### <span id="IsWindows">IsWindows</span>
|
||||
|
||||
<p>检查当前操作系统是否是windows</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -44,24 +45,23 @@ import (
|
||||
```go
|
||||
func IsWindows() bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
isOsWindows := system.IsWindows()
|
||||
fmt.Println(isOsWindows)
|
||||
isOsWindows := system.IsWindows()
|
||||
fmt.Println(isOsWindows)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsLinux">IsLinux</span>
|
||||
|
||||
<p>检查当前操作系统是否是linux</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -69,23 +69,23 @@ func main() {
|
||||
```go
|
||||
func IsLinux() bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
isOsLinux := system.IsLinux()
|
||||
fmt.Println(isOsLinux)
|
||||
isOsLinux := system.IsLinux()
|
||||
fmt.Println(isOsLinux)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="IsMac">IsMac</span>
|
||||
|
||||
<p>检查当前操作系统是否是macos</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -93,23 +93,23 @@ func main() {
|
||||
```go
|
||||
func IsMac() bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
isOsMac := system.IsMac()
|
||||
fmt.Println(isOsMac)
|
||||
isOsMac := system.IsMac()
|
||||
fmt.Println(isOsMac)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="GetOsEnv">GetOsEnv</span>
|
||||
|
||||
<p>获取key命名的环境变量的值</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -117,23 +117,29 @@ func main() {
|
||||
```go
|
||||
func GetOsEnv(key string) string
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fooEnv := system.GetOsEnv("foo")
|
||||
fmt.Println(fooEnv)
|
||||
err := system.SetOsEnv("foo", "abc")
|
||||
result := system.GetOsEnv("foo")
|
||||
|
||||
fmt.Println(err)
|
||||
fmt.Println(result)
|
||||
// Output:
|
||||
// <nil>
|
||||
// abc
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="SetOsEnv">SetOsEnv</span>
|
||||
|
||||
<p>设置由key命名的环境变量的值</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -141,24 +147,29 @@ func main() {
|
||||
```go
|
||||
func SetOsEnv(key, value string) error
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := system.SetOsEnv("foo", "foo_value")
|
||||
fmt.Println(err)
|
||||
err := system.SetOsEnv("foo", "abc")
|
||||
result := system.GetOsEnv("foo")
|
||||
|
||||
fmt.Println(err)
|
||||
fmt.Println(result)
|
||||
// Output:
|
||||
// <nil>
|
||||
// abc
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="RemoveOsEnv">RemoveOsEnv</span>
|
||||
|
||||
<p>删除单个环境变量</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -166,25 +177,37 @@ func main() {
|
||||
```go
|
||||
func RemoveOsEnv(key string) error
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := system.RemoveOsEnv("foo")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
err1 := system.SetOsEnv("foo", "abc")
|
||||
result1 := GetOsEnv("foo")
|
||||
|
||||
err2 := system.RemoveOsEnv("foo")
|
||||
result2 := GetOsEnv("foo")
|
||||
|
||||
fmt.Println(err1)
|
||||
fmt.Println(err2)
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// <nil>
|
||||
// <nil>
|
||||
// abc
|
||||
//
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="CompareOsEnv">CompareOsEnv</span>
|
||||
|
||||
<p>获取key命名的环境变量值并与compareEnv进行比较</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -192,25 +215,32 @@ func main() {
|
||||
```go
|
||||
func CompareOsEnv(key, comparedEnv string) bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
system.SetOsEnv("foo", "foo_value")
|
||||
res := system.CompareOsEnv("foo", "foo_value")
|
||||
fmt.Println(res) //true
|
||||
err := system.SetOsEnv("foo", "abc")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
result := system.CompareOsEnv("foo", "abc")
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="ExecCommand">ExecCommand</span>
|
||||
|
||||
<p>执行shell命令,返回命令的stdout和stderr字符串,如果出现错误,则返回错误。参数`command`是一个完整的命令字符串,如ls-a(linux),dir(windows),ping 127.0.0.1。在linux中,使用/bin/bash-c执行命令,在windows中,使用powershell.exe执行命令。</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -218,40 +248,39 @@ func main() {
|
||||
```go
|
||||
func ExecCommand(command string) (stdout, stderr string, err error)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// linux or mac
|
||||
stdout, stderr, err := system.ExecCommand("ls")
|
||||
fmt.Println("std out: ", stdout)
|
||||
fmt.Println("std err: ", stderr)
|
||||
assert.Equal("", stderr)
|
||||
// linux or mac
|
||||
stdout, stderr, err := system.ExecCommand("ls")
|
||||
fmt.Println("std out: ", stdout)
|
||||
fmt.Println("std err: ", stderr)
|
||||
assert.Equal("", stderr)
|
||||
|
||||
// windows
|
||||
stdout, stderr, err = system.ExecCommand("dir")
|
||||
fmt.Println("std out: ", stdout)
|
||||
fmt.Println("std err: ", stderr)
|
||||
// windows
|
||||
stdout, stderr, err = system.ExecCommand("dir")
|
||||
fmt.Println("std out: ", stdout)
|
||||
fmt.Println("std err: ", stderr)
|
||||
|
||||
// error command
|
||||
stdout, stderr, err = system.ExecCommand("abc")
|
||||
fmt.Println("std out: ", stdout)
|
||||
fmt.Println("std err: ", stderr)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
// error command
|
||||
stdout, stderr, err = system.ExecCommand("abc")
|
||||
fmt.Println("std out: ", stdout)
|
||||
fmt.Println("std err: ", stderr)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="GetOsBits">GetOsBits</span>
|
||||
|
||||
<p>获取当前操作系统位数,返回32或64</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -259,23 +288,17 @@ func main() {
|
||||
```go
|
||||
func GetOsBits() int
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
osBit := system.GetOsBits()
|
||||
fmt.Println(osBit)
|
||||
osBit := system.GetOsBits()
|
||||
fmt.Println(osBit) // 32 or 64
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,15 +1,17 @@
|
||||
# Xerror
|
||||
|
||||
Package xerror implements helpers for errors.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/xerror/xerror.go](https://github.com/duke-git/lancet/blob/main/xerror/xerror.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/xerror/xerror.go](https://github.com/duke-git/lancet/blob/main/xerror/xerror.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Usage:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/xerror"
|
||||
@@ -19,15 +21,15 @@ import (
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [Unwrap](#Unwrap)
|
||||
|
||||
- [Unwrap](#Unwrap)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
|
||||
### <span id="Unwrap">Unwrap</span>
|
||||
|
||||
<p>Unwrap if err is nil then it returns a valid value. If err is not nil, Unwrap panics with err.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
@@ -35,6 +37,7 @@ import (
|
||||
```go
|
||||
func Unwrap[T any](val T, err error) T
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
@@ -46,20 +49,20 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := xerror.Unwrap(strconv.Atoi("42"))
|
||||
fmt.Println(result1)
|
||||
result1 := xerror.Unwrap(strconv.Atoi("42"))
|
||||
fmt.Println(result1)
|
||||
|
||||
_, err := strconv.Atoi("4o2")
|
||||
defer func() {
|
||||
v := recover()
|
||||
result2 := reflect.DeepEqual(err.Error(), v.(*strconv.NumError).Error())
|
||||
fmt.Println(result2)
|
||||
}()
|
||||
_, err := strconv.Atoi("4o2")
|
||||
defer func() {
|
||||
v := recover()
|
||||
result2 := reflect.DeepEqual(err.Error(), v.(*strconv.NumError).Error())
|
||||
fmt.Println(result2)
|
||||
}()
|
||||
|
||||
xerror.Unwrap(strconv.Atoi("4o2"))
|
||||
xerror.Unwrap(strconv.Atoi("4o2"))
|
||||
|
||||
// Output:
|
||||
// 42
|
||||
// true
|
||||
// Output:
|
||||
// 42
|
||||
// true
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
# Xerror
|
||||
xerror错误处理逻辑封装
|
||||
|
||||
xerror 错误处理逻辑封装
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/xerror/xerror.go](https://github.com/duke-git/lancet/blob/main/xerror/xerror.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/xerror/xerror.go](https://github.com/duke-git/lancet/blob/main/xerror/xerror.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/xerror"
|
||||
@@ -19,15 +21,15 @@ import (
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录
|
||||
- [Unwrap](#Unwrap)
|
||||
|
||||
- [Unwrap](#Unwrap)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 文档
|
||||
|
||||
|
||||
|
||||
### <span id="Unwrap">Unwrap</span>
|
||||
|
||||
<p>检查error, 如果err为nil则展开,则它返回一个有效值,如果err不是nil则Unwrap使用err发生panic。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
@@ -35,7 +37,8 @@ import (
|
||||
```go
|
||||
func Unwrap[T any](val T, err error) T
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -46,20 +49,20 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := xerror.Unwrap(strconv.Atoi("42"))
|
||||
fmt.Println(result1)
|
||||
result1 := xerror.Unwrap(strconv.Atoi("42"))
|
||||
fmt.Println(result1)
|
||||
|
||||
_, err := strconv.Atoi("4o2")
|
||||
defer func() {
|
||||
v := recover()
|
||||
result2 := reflect.DeepEqual(err.Error(), v.(*strconv.NumError).Error())
|
||||
fmt.Println(result2)
|
||||
}()
|
||||
_, err := strconv.Atoi("4o2")
|
||||
defer func() {
|
||||
v := recover()
|
||||
result2 := reflect.DeepEqual(err.Error(), v.(*strconv.NumError).Error())
|
||||
fmt.Println(result2)
|
||||
}()
|
||||
|
||||
xerror.Unwrap(strconv.Atoi("4o2"))
|
||||
xerror.Unwrap(strconv.Atoi("4o2"))
|
||||
|
||||
// Output:
|
||||
// 42
|
||||
// true
|
||||
// Output:
|
||||
// 42
|
||||
// true
|
||||
}
|
||||
```
|
||||
|
||||
@@ -47,7 +47,7 @@ func Before(n int, fn any) func(args ...any) []reflect.Value {
|
||||
type CurryFn[T any] func(...T) T
|
||||
|
||||
// New make a curry function for specific value.
|
||||
// Play: Todo
|
||||
// Play: https://go.dev/play/p/5HopfDwANKX
|
||||
func (cf CurryFn[T]) New(val T) func(...T) T {
|
||||
return func(vals ...T) T {
|
||||
args := append([]T{val}, vals...)
|
||||
@@ -56,7 +56,7 @@ func (cf CurryFn[T]) New(val T) func(...T) T {
|
||||
}
|
||||
|
||||
// Compose compose the functions from right to left.
|
||||
// Play: Todo
|
||||
// Play: https://go.dev/play/p/KKfugD4PKYF
|
||||
func Compose[T any](fnList ...func(...T) T) func(...T) T {
|
||||
return func(args ...T) T {
|
||||
firstFn := fnList[0]
|
||||
|
||||
@@ -114,15 +114,15 @@ func ExampleSchedule() {
|
||||
count++
|
||||
}
|
||||
|
||||
stop := Schedule(1*time.Second, increase)
|
||||
stop := Schedule(2*time.Second, increase)
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
time.Sleep(2 * time.Second)
|
||||
close(stop)
|
||||
|
||||
fmt.Println(count)
|
||||
|
||||
// Output:
|
||||
// 3
|
||||
// 2
|
||||
}
|
||||
|
||||
func ExamplePipeline() {
|
||||
|
||||
@@ -3,7 +3,7 @@ package function
|
||||
import "time"
|
||||
|
||||
// Watcher is used for record code excution time
|
||||
// Play: Todo
|
||||
// Play: https://go.dev/play/p/l2yrOpCLd1I
|
||||
type Watcher struct {
|
||||
startTime int64
|
||||
stopTime int64
|
||||
|
||||
@@ -55,7 +55,7 @@ func Factorial(x uint) uint {
|
||||
}
|
||||
|
||||
// Percent calculate the percentage of value to total.
|
||||
// Play: Todo
|
||||
// Play: https://go.dev/play/p/QQM9B13coSP
|
||||
func Percent(val, total float64, n int) float64 {
|
||||
if total == 0 {
|
||||
return float64(0)
|
||||
|
||||
226
netutil/http.go
226
netutil/http.go
@@ -13,12 +13,21 @@
|
||||
package netutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/duke-git/lancet/v2/slice"
|
||||
)
|
||||
|
||||
// HttpGet send get http request.
|
||||
@@ -78,3 +87,220 @@ func ConvertMapToQueryString(param map[string]any) string {
|
||||
}
|
||||
return build.String()
|
||||
}
|
||||
|
||||
// HttpRequest struct is a composed http request
|
||||
type HttpRequest struct {
|
||||
RawURL string
|
||||
Method string
|
||||
Headers http.Header
|
||||
QueryParams url.Values
|
||||
FormData url.Values
|
||||
Body []byte
|
||||
}
|
||||
|
||||
// HttpClientConfig contains some configurations for http client
|
||||
type HttpClientConfig struct {
|
||||
SSLEnabled bool
|
||||
TLSConfig *tls.Config
|
||||
Compressed bool
|
||||
HandshakeTimeout time.Duration
|
||||
ResponseTimeout time.Duration
|
||||
Verbose bool
|
||||
}
|
||||
|
||||
// defaultHttpClientConfig defalut client config
|
||||
var defaultHttpClientConfig = &HttpClientConfig{
|
||||
Compressed: false,
|
||||
HandshakeTimeout: 20 * time.Second,
|
||||
ResponseTimeout: 40 * time.Second,
|
||||
}
|
||||
|
||||
// HttpClient is used for sending http request
|
||||
type HttpClient struct {
|
||||
*http.Client
|
||||
TLS *tls.Config
|
||||
Request *http.Request
|
||||
Config HttpClientConfig
|
||||
}
|
||||
|
||||
// NewHttpClient make a HttpClient instance
|
||||
func NewHttpClient() *HttpClient {
|
||||
client := &HttpClient{
|
||||
Client: &http.Client{
|
||||
Transport: &http.Transport{
|
||||
TLSHandshakeTimeout: defaultHttpClientConfig.HandshakeTimeout,
|
||||
ResponseHeaderTimeout: defaultHttpClientConfig.ResponseTimeout,
|
||||
DisableCompression: !defaultHttpClientConfig.Compressed,
|
||||
},
|
||||
},
|
||||
Config: *defaultHttpClientConfig,
|
||||
}
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
// NewHttpClientWithConfig make a HttpClient instance with pass config
|
||||
func NewHttpClientWithConfig(config *HttpClientConfig) *HttpClient {
|
||||
if config == nil {
|
||||
config = defaultHttpClientConfig
|
||||
}
|
||||
|
||||
client := &HttpClient{
|
||||
Client: &http.Client{
|
||||
Transport: &http.Transport{
|
||||
TLSHandshakeTimeout: config.HandshakeTimeout,
|
||||
ResponseHeaderTimeout: config.ResponseTimeout,
|
||||
DisableCompression: !config.Compressed,
|
||||
},
|
||||
},
|
||||
Config: *config,
|
||||
}
|
||||
|
||||
if config.SSLEnabled {
|
||||
client.TLS = config.TLSConfig
|
||||
}
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
// SendRequest send http request.
|
||||
// Play: https://go.dev/play/p/jUSgynekH7G
|
||||
func (client *HttpClient) SendRequest(request *HttpRequest) (*http.Response, error) {
|
||||
err := validateRequest(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rawUrl := request.RawURL
|
||||
|
||||
req, err := http.NewRequest(request.Method, rawUrl, bytes.NewBuffer(request.Body))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client.setTLS(rawUrl)
|
||||
client.setHeader(req, request.Headers)
|
||||
|
||||
err = client.setQueryParam(req, rawUrl, request.QueryParams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if request.FormData != nil {
|
||||
client.setFormData(req, request.FormData)
|
||||
}
|
||||
|
||||
client.Request = req
|
||||
|
||||
resp, err := client.Client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// DecodeResponse decode response into target object.
|
||||
// Play: https://go.dev/play/p/jUSgynekH7G
|
||||
func (client *HttpClient) DecodeResponse(resp *http.Response, target any) error {
|
||||
if resp == nil {
|
||||
return errors.New("invalid target param")
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
return json.NewDecoder(resp.Body).Decode(target)
|
||||
}
|
||||
|
||||
// setTLS set http client transport TLSClientConfig
|
||||
func (client *HttpClient) setTLS(rawUrl string) {
|
||||
if strings.HasPrefix(rawUrl, "https") {
|
||||
if transport, ok := client.Client.Transport.(*http.Transport); ok {
|
||||
transport.TLSClientConfig = client.TLS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// setHeader set http rquest header
|
||||
func (client *HttpClient) setHeader(req *http.Request, headers http.Header) {
|
||||
if headers == nil {
|
||||
headers = make(http.Header)
|
||||
}
|
||||
|
||||
if _, ok := headers["Accept"]; !ok {
|
||||
headers["Accept"] = []string{"*/*"}
|
||||
}
|
||||
if _, ok := headers["Accept-Encoding"]; !ok && client.Config.Compressed {
|
||||
headers["Accept-Encoding"] = []string{"deflate, gzip"}
|
||||
}
|
||||
|
||||
req.Header = headers
|
||||
}
|
||||
|
||||
// setQueryParam set http request query string param
|
||||
func (client *HttpClient) setQueryParam(req *http.Request, reqUrl string, queryParam url.Values) error {
|
||||
if queryParam != nil {
|
||||
if !strings.Contains(reqUrl, "?") {
|
||||
reqUrl = reqUrl + "?" + queryParam.Encode()
|
||||
} else {
|
||||
reqUrl = reqUrl + "&" + queryParam.Encode()
|
||||
}
|
||||
u, err := url.Parse(reqUrl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.URL = u
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (client *HttpClient) setFormData(req *http.Request, values url.Values) {
|
||||
formData := []byte(values.Encode())
|
||||
req.Body = io.NopCloser(bytes.NewReader(formData))
|
||||
req.ContentLength = int64(len(formData))
|
||||
}
|
||||
|
||||
// validateRequest check if a request has url, and valid method.
|
||||
func validateRequest(req *HttpRequest) error {
|
||||
if req.RawURL == "" {
|
||||
return errors.New("invalid request url")
|
||||
}
|
||||
|
||||
// common HTTP methods
|
||||
methods := []string{"GET", "POST", "PUT", "DELETE", "PATCH",
|
||||
"HEAD", "CONNECT", "OPTIONS", "TRACE"}
|
||||
|
||||
if !slice.Contain(methods, strings.ToUpper(req.Method)) {
|
||||
return errors.New("invalid request method")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// StructToUrlValues convert struct to url valuse,
|
||||
// only convert the field which is exported and has `json` tag.
|
||||
// Play: https://go.dev/play/p/pFqMkM40w9z
|
||||
func StructToUrlValues(targetStruct any) url.Values {
|
||||
rv := reflect.ValueOf(targetStruct)
|
||||
rt := reflect.TypeOf(targetStruct)
|
||||
|
||||
if rt.Kind() == reflect.Ptr {
|
||||
rt = rt.Elem()
|
||||
}
|
||||
if rt.Kind() != reflect.Struct {
|
||||
panic(fmt.Errorf("data type %T not support, shuld be struct or pointer to struct", targetStruct))
|
||||
}
|
||||
|
||||
result := url.Values{}
|
||||
|
||||
fieldNum := rt.NumField()
|
||||
pattern := `^[A-Z]`
|
||||
regex := regexp.MustCompile(pattern)
|
||||
for i := 0; i < fieldNum; i++ {
|
||||
name := rt.Field(i).Name
|
||||
tag := rt.Field(i).Tag.Get("json")
|
||||
if regex.MatchString(name) && tag != "" {
|
||||
result.Add(tag, fmt.Sprintf("%v", rv.Field(i).Interface()))
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -1,235 +0,0 @@
|
||||
package netutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/duke-git/lancet/v2/slice"
|
||||
)
|
||||
|
||||
// HttpRequest struct is a composed http request
|
||||
type HttpRequest struct {
|
||||
RawURL string
|
||||
Method string
|
||||
Headers http.Header
|
||||
QueryParams url.Values
|
||||
FormData url.Values
|
||||
Body []byte
|
||||
}
|
||||
|
||||
// HttpClientConfig contains some configurations for http client
|
||||
type HttpClientConfig struct {
|
||||
SSLEnabled bool
|
||||
TLSConfig *tls.Config
|
||||
Compressed bool
|
||||
HandshakeTimeout time.Duration
|
||||
ResponseTimeout time.Duration
|
||||
Verbose bool
|
||||
}
|
||||
|
||||
// defaultHttpClientConfig defalut client config
|
||||
var defaultHttpClientConfig = &HttpClientConfig{
|
||||
Compressed: false,
|
||||
HandshakeTimeout: 20 * time.Second,
|
||||
ResponseTimeout: 40 * time.Second,
|
||||
}
|
||||
|
||||
// HttpClient is used for sending http request
|
||||
type HttpClient struct {
|
||||
*http.Client
|
||||
TLS *tls.Config
|
||||
Request *http.Request
|
||||
Config HttpClientConfig
|
||||
}
|
||||
|
||||
// NewHttpClient make a HttpClient instance
|
||||
func NewHttpClient() *HttpClient {
|
||||
client := &HttpClient{
|
||||
Client: &http.Client{
|
||||
Transport: &http.Transport{
|
||||
TLSHandshakeTimeout: defaultHttpClientConfig.HandshakeTimeout,
|
||||
ResponseHeaderTimeout: defaultHttpClientConfig.ResponseTimeout,
|
||||
DisableCompression: !defaultHttpClientConfig.Compressed,
|
||||
},
|
||||
},
|
||||
Config: *defaultHttpClientConfig,
|
||||
}
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
// NewHttpClientWithConfig make a HttpClient instance with pass config
|
||||
func NewHttpClientWithConfig(config *HttpClientConfig) *HttpClient {
|
||||
if config == nil {
|
||||
config = defaultHttpClientConfig
|
||||
}
|
||||
|
||||
client := &HttpClient{
|
||||
Client: &http.Client{
|
||||
Transport: &http.Transport{
|
||||
TLSHandshakeTimeout: config.HandshakeTimeout,
|
||||
ResponseHeaderTimeout: config.ResponseTimeout,
|
||||
DisableCompression: !config.Compressed,
|
||||
},
|
||||
},
|
||||
Config: *config,
|
||||
}
|
||||
|
||||
if config.SSLEnabled {
|
||||
client.TLS = config.TLSConfig
|
||||
}
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
// SendRequest send http request.
|
||||
// Play: https://go.dev/play/p/jUSgynekH7G
|
||||
func (client *HttpClient) SendRequest(request *HttpRequest) (*http.Response, error) {
|
||||
err := validateRequest(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rawUrl := request.RawURL
|
||||
|
||||
req, err := http.NewRequest(request.Method, rawUrl, bytes.NewBuffer(request.Body))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client.setTLS(rawUrl)
|
||||
client.setHeader(req, request.Headers)
|
||||
|
||||
err = client.setQueryParam(req, rawUrl, request.QueryParams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if request.FormData != nil {
|
||||
client.setFormData(req, request.FormData)
|
||||
}
|
||||
|
||||
client.Request = req
|
||||
|
||||
resp, err := client.Client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// DecodeResponse decode response into target object.
|
||||
// Play: https://go.dev/play/p/jUSgynekH7G
|
||||
func (client *HttpClient) DecodeResponse(resp *http.Response, target any) error {
|
||||
if resp == nil {
|
||||
return errors.New("invalid target param")
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
return json.NewDecoder(resp.Body).Decode(target)
|
||||
}
|
||||
|
||||
// setTLS set http client transport TLSClientConfig
|
||||
func (client *HttpClient) setTLS(rawUrl string) {
|
||||
if strings.HasPrefix(rawUrl, "https") {
|
||||
if transport, ok := client.Client.Transport.(*http.Transport); ok {
|
||||
transport.TLSClientConfig = client.TLS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// setHeader set http rquest header
|
||||
func (client *HttpClient) setHeader(req *http.Request, headers http.Header) {
|
||||
if headers == nil {
|
||||
headers = make(http.Header)
|
||||
}
|
||||
|
||||
if _, ok := headers["Accept"]; !ok {
|
||||
headers["Accept"] = []string{"*/*"}
|
||||
}
|
||||
if _, ok := headers["Accept-Encoding"]; !ok && client.Config.Compressed {
|
||||
headers["Accept-Encoding"] = []string{"deflate, gzip"}
|
||||
}
|
||||
|
||||
req.Header = headers
|
||||
}
|
||||
|
||||
// setQueryParam set http request query string param
|
||||
func (client *HttpClient) setQueryParam(req *http.Request, reqUrl string, queryParam url.Values) error {
|
||||
if queryParam != nil {
|
||||
if !strings.Contains(reqUrl, "?") {
|
||||
reqUrl = reqUrl + "?" + queryParam.Encode()
|
||||
} else {
|
||||
reqUrl = reqUrl + "&" + queryParam.Encode()
|
||||
}
|
||||
u, err := url.Parse(reqUrl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.URL = u
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (client *HttpClient) setFormData(req *http.Request, values url.Values) {
|
||||
formData := []byte(values.Encode())
|
||||
req.Body = io.NopCloser(bytes.NewReader(formData))
|
||||
req.ContentLength = int64(len(formData))
|
||||
}
|
||||
|
||||
// validateRequest check if a request has url, and valid method.
|
||||
func validateRequest(req *HttpRequest) error {
|
||||
if req.RawURL == "" {
|
||||
return errors.New("invalid request url")
|
||||
}
|
||||
|
||||
// common HTTP methods
|
||||
methods := []string{"GET", "POST", "PUT", "DELETE", "PATCH",
|
||||
"HEAD", "CONNECT", "OPTIONS", "TRACE"}
|
||||
|
||||
if !slice.Contain(methods, strings.ToUpper(req.Method)) {
|
||||
return errors.New("invalid request method")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// StructToUrlValues convert struct to url valuse,
|
||||
// only convert the field which is exported and has `json` tag.
|
||||
// Play: https://go.dev/play/p/pFqMkM40w9z
|
||||
func StructToUrlValues(targetStruct any) url.Values {
|
||||
rv := reflect.ValueOf(targetStruct)
|
||||
rt := reflect.TypeOf(targetStruct)
|
||||
|
||||
if rt.Kind() == reflect.Ptr {
|
||||
rt = rt.Elem()
|
||||
}
|
||||
if rt.Kind() != reflect.Struct {
|
||||
panic(fmt.Errorf("data type %T not support, shuld be struct or pointer to struct", targetStruct))
|
||||
}
|
||||
|
||||
result := url.Values{}
|
||||
|
||||
fieldNum := rt.NumField()
|
||||
pattern := `^[A-Z]`
|
||||
regex := regexp.MustCompile(pattern)
|
||||
for i := 0; i < fieldNum; i++ {
|
||||
name := rt.Field(i).Name
|
||||
tag := rt.Field(i).Tag.Get("json")
|
||||
if regex.MatchString(name) && tag != "" {
|
||||
result.Add(tag, fmt.Sprintf("%v", rv.Field(i).Interface()))
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
package netutil
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestHttpClient_Get(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestHttpClient_Get")
|
||||
|
||||
request := &HttpRequest{
|
||||
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
|
||||
Method: "GET",
|
||||
}
|
||||
|
||||
httpClient := NewHttpClient()
|
||||
resp, err := httpClient.SendRequest(request)
|
||||
if err != nil || resp.StatusCode != 200 {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
type Todo struct {
|
||||
UserId int `json:"userId"`
|
||||
Id int `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Completed bool `json:"completed"`
|
||||
}
|
||||
|
||||
var todo Todo
|
||||
err = httpClient.DecodeResponse(resp, &todo)
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
}
|
||||
|
||||
assert.Equal(1, todo.Id)
|
||||
}
|
||||
|
||||
func TestHttpClent_Post(t *testing.T) {
|
||||
header := http.Header{}
|
||||
header.Add("Content-Type", "multipart/form-data")
|
||||
|
||||
postData := url.Values{}
|
||||
postData.Add("userId", "1")
|
||||
postData.Add("title", "testItem")
|
||||
|
||||
request := &HttpRequest{
|
||||
RawURL: "https://jsonplaceholder.typicode.com/todos",
|
||||
Method: "POST",
|
||||
Headers: header,
|
||||
FormData: postData,
|
||||
}
|
||||
|
||||
httpClient := NewHttpClient()
|
||||
resp, err := httpClient.SendRequest(request)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
t.Log("response: ", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
func TestStructToUrlValues(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestStructToUrlValues")
|
||||
|
||||
type TodoQuery struct {
|
||||
Id int `json:"id"`
|
||||
UserId int `json:"userId"`
|
||||
}
|
||||
todoQuery := TodoQuery{
|
||||
Id: 1,
|
||||
UserId: 1,
|
||||
}
|
||||
todoValues := StructToUrlValues(todoQuery)
|
||||
|
||||
assert.Equal("1", todoValues.Get("id"))
|
||||
assert.Equal("1", todoValues.Get("userId"))
|
||||
|
||||
request := &HttpRequest{
|
||||
RawURL: "https://jsonplaceholder.typicode.com/todos",
|
||||
Method: "GET",
|
||||
QueryParams: todoValues,
|
||||
}
|
||||
|
||||
httpClient := NewHttpClient()
|
||||
resp, err := httpClient.SendRequest(request)
|
||||
if err != nil || resp.StatusCode != 200 {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
t.Log("response: ", string(body))
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
package netutil
|
||||
|
||||
import "fmt"
|
||||
|
||||
func ExampleHttpClient_SendRequest() {
|
||||
request := &HttpRequest{
|
||||
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
|
||||
Method: "GET",
|
||||
}
|
||||
|
||||
httpClient := NewHttpClient()
|
||||
resp, err := httpClient.SendRequest(request)
|
||||
if err != nil || resp.StatusCode != 200 {
|
||||
return
|
||||
}
|
||||
|
||||
type Todo struct {
|
||||
UserId int `json:"userId"`
|
||||
Id int `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Completed bool `json:"completed"`
|
||||
}
|
||||
|
||||
var todo Todo
|
||||
err = httpClient.DecodeResponse(resp, &todo)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(todo.Id)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
}
|
||||
|
||||
func ExampleHttpClient_DecodeResponse() {
|
||||
request := &HttpRequest{
|
||||
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
|
||||
Method: "GET",
|
||||
}
|
||||
|
||||
httpClient := NewHttpClient()
|
||||
resp, err := httpClient.SendRequest(request)
|
||||
if err != nil || resp.StatusCode != 200 {
|
||||
return
|
||||
}
|
||||
|
||||
type Todo struct {
|
||||
UserId int `json:"userId"`
|
||||
Id int `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Completed bool `json:"completed"`
|
||||
}
|
||||
|
||||
var todo Todo
|
||||
err = httpClient.DecodeResponse(resp, &todo)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(todo.Id)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
}
|
||||
|
||||
func ExampleStructToUrlValues() {
|
||||
type TodoQuery struct {
|
||||
Id int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
todoQuery := TodoQuery{
|
||||
Id: 1,
|
||||
Name: "Test",
|
||||
}
|
||||
todoValues := StructToUrlValues(todoQuery)
|
||||
|
||||
fmt.Println(todoValues.Get("id"))
|
||||
fmt.Println(todoValues.Get("name"))
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// Test
|
||||
}
|
||||
|
||||
func ExampleConvertMapToQueryString() {
|
||||
var m = map[string]any{
|
||||
"c": 3,
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
}
|
||||
|
||||
qs := ConvertMapToQueryString(m)
|
||||
|
||||
fmt.Println(qs)
|
||||
|
||||
// Output:
|
||||
// a=1&b=2&c=3
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
@@ -156,3 +157,90 @@ func TestParseResponse(t *testing.T) {
|
||||
}
|
||||
t.Log("response: ", toDoResp)
|
||||
}
|
||||
|
||||
func TestHttpClient_Get(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestHttpClient_Get")
|
||||
|
||||
request := &HttpRequest{
|
||||
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
|
||||
Method: "GET",
|
||||
}
|
||||
|
||||
httpClient := NewHttpClient()
|
||||
resp, err := httpClient.SendRequest(request)
|
||||
if err != nil || resp.StatusCode != 200 {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
type Todo struct {
|
||||
UserId int `json:"userId"`
|
||||
Id int `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Completed bool `json:"completed"`
|
||||
}
|
||||
|
||||
var todo Todo
|
||||
err = httpClient.DecodeResponse(resp, &todo)
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
}
|
||||
|
||||
assert.Equal(1, todo.Id)
|
||||
}
|
||||
|
||||
func TestHttpClent_Post(t *testing.T) {
|
||||
header := http.Header{}
|
||||
header.Add("Content-Type", "multipart/form-data")
|
||||
|
||||
postData := url.Values{}
|
||||
postData.Add("userId", "1")
|
||||
postData.Add("title", "testItem")
|
||||
|
||||
request := &HttpRequest{
|
||||
RawURL: "https://jsonplaceholder.typicode.com/todos",
|
||||
Method: "POST",
|
||||
Headers: header,
|
||||
FormData: postData,
|
||||
}
|
||||
|
||||
httpClient := NewHttpClient()
|
||||
resp, err := httpClient.SendRequest(request)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
t.Log("response: ", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
func TestStructToUrlValues(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestStructToUrlValues")
|
||||
|
||||
type TodoQuery struct {
|
||||
Id int `json:"id"`
|
||||
UserId int `json:"userId"`
|
||||
}
|
||||
todoQuery := TodoQuery{
|
||||
Id: 1,
|
||||
UserId: 1,
|
||||
}
|
||||
todoValues := StructToUrlValues(todoQuery)
|
||||
|
||||
assert.Equal("1", todoValues.Get("id"))
|
||||
assert.Equal("1", todoValues.Get("userId"))
|
||||
|
||||
request := &HttpRequest{
|
||||
RawURL: "https://jsonplaceholder.typicode.com/todos",
|
||||
Method: "GET",
|
||||
QueryParams: todoValues,
|
||||
}
|
||||
|
||||
httpClient := NewHttpClient()
|
||||
resp, err := httpClient.SendRequest(request)
|
||||
if err != nil || resp.StatusCode != 200 {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
t.Log("response: ", string(body))
|
||||
}
|
||||
|
||||
@@ -89,3 +89,68 @@ func ExampleEncodeUrl() {
|
||||
// Output:
|
||||
// http://www.lancet.com?a=1&b=%5B2%5D
|
||||
}
|
||||
|
||||
func ExampleHttpClient_DecodeResponse() {
|
||||
request := &HttpRequest{
|
||||
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
|
||||
Method: "GET",
|
||||
}
|
||||
|
||||
httpClient := NewHttpClient()
|
||||
resp, err := httpClient.SendRequest(request)
|
||||
if err != nil || resp.StatusCode != 200 {
|
||||
return
|
||||
}
|
||||
|
||||
type Todo struct {
|
||||
UserId int `json:"userId"`
|
||||
Id int `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Completed bool `json:"completed"`
|
||||
}
|
||||
|
||||
var todo Todo
|
||||
err = httpClient.DecodeResponse(resp, &todo)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(todo.Id)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
}
|
||||
|
||||
func ExampleStructToUrlValues() {
|
||||
type TodoQuery struct {
|
||||
Id int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
todoQuery := TodoQuery{
|
||||
Id: 1,
|
||||
Name: "Test",
|
||||
}
|
||||
todoValues := StructToUrlValues(todoQuery)
|
||||
|
||||
fmt.Println(todoValues.Get("id"))
|
||||
fmt.Println(todoValues.Get("name"))
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// Test
|
||||
}
|
||||
|
||||
func ExampleConvertMapToQueryString() {
|
||||
var m = map[string]any{
|
||||
"c": 3,
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
}
|
||||
|
||||
qs := ConvertMapToQueryString(m)
|
||||
|
||||
fmt.Println(qs)
|
||||
|
||||
// Output:
|
||||
// a=1&b=2&c=3
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
)
|
||||
|
||||
func ExampleRandInt() {
|
||||
|
||||
result := RandInt(1, 10)
|
||||
|
||||
if result >= 1 && result < 10 {
|
||||
|
||||
261
stream/stream.go
Normal file
261
stream/stream.go
Normal file
@@ -0,0 +1,261 @@
|
||||
// Copyright 2023 dudaodong@gmail.com. All rights resulterved.
|
||||
// Use of this source code is governed by MIT license
|
||||
|
||||
// Package stream implements a sequence of elements supporting sequential and parallel aggregate operations.
|
||||
// this package is an experiment to explore if stream in go can work as the way java does. it's complete, but not
|
||||
// powerful like other libs
|
||||
package stream
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
|
||||
"golang.org/x/exp/constraints"
|
||||
)
|
||||
|
||||
// A stream should implements methods:
|
||||
// type StreamI[T any] interface {
|
||||
|
||||
// // part methods of Java Stream Specification.
|
||||
// Distinct() StreamI[T]
|
||||
// Filter(predicate func(item T) bool) StreamI[T]
|
||||
// FlatMap(mapper func(item T) StreamI[T]) StreamI[T]
|
||||
// Map(mapper func(item T) T) StreamI[T]
|
||||
// Peek(consumer func(item T)) StreamI[T]
|
||||
|
||||
// Sort(less func(a, b T) bool) StreamI[T]
|
||||
// Max(less func(a, b T) bool) (T, bool)
|
||||
// Min(less func(a, b T) bool) (T, bool)
|
||||
|
||||
// Limit(maxSize int) StreamI[T]
|
||||
// Skip(n int) StreamI[T]
|
||||
|
||||
// AllMatch(predicate func(item T) bool) bool
|
||||
// AnyMatch(predicate func(item T) bool) bool
|
||||
// NoneMatch(predicate func(item T) bool) bool
|
||||
// ForEach(consumer func(item T))
|
||||
// Reduce(init T, accumulator func(a, b T) T) T
|
||||
// Count() int
|
||||
|
||||
// FindFirst() (T, bool)
|
||||
|
||||
// ToSlice() []T
|
||||
|
||||
// // part of methods custom extension
|
||||
// Reverse() StreamI[T]
|
||||
// Range(start, end int64) StreamI[T]
|
||||
// Concat(streams ...StreamI[T]) StreamI[T]
|
||||
// }
|
||||
|
||||
type stream[T any] struct {
|
||||
source []T
|
||||
}
|
||||
|
||||
// Of creates a stream stream whose elements are the specified values.
|
||||
func Of[T any](elems ...T) stream[T] {
|
||||
return FromSlice(elems)
|
||||
}
|
||||
|
||||
// Generate stream where each element is generated by the provided generater function
|
||||
// generater function: func() func() (item T, ok bool) {}
|
||||
func Generate[T any](generator func() func() (item T, ok bool)) stream[T] {
|
||||
source := make([]T, 0)
|
||||
|
||||
var zeroValue T
|
||||
for next, item, ok := generator(), zeroValue, true; ok; {
|
||||
item, ok = next()
|
||||
if ok {
|
||||
source = append(source, item)
|
||||
}
|
||||
}
|
||||
|
||||
return FromSlice(source)
|
||||
}
|
||||
|
||||
// FromSlice create stream from slice.
|
||||
func FromSlice[T any](source []T) stream[T] {
|
||||
return stream[T]{source: source}
|
||||
}
|
||||
|
||||
// FromChannel create stream from channel.
|
||||
func FromChannel[T any](source <-chan T) stream[T] {
|
||||
s := make([]T, 0)
|
||||
|
||||
for v := range source {
|
||||
s = append(s, v)
|
||||
}
|
||||
|
||||
return FromSlice(s)
|
||||
}
|
||||
|
||||
// FromRange create a number stream from start to end. both start and end are included. [start, end]
|
||||
func FromRange[T constraints.Integer | constraints.Float](start, end, step T) stream[T] {
|
||||
if end < start {
|
||||
panic("stream.FromRange: param start should be before param end")
|
||||
} else if step <= 0 {
|
||||
panic("stream.FromRange: param step should be positive")
|
||||
}
|
||||
|
||||
l := int((end-start)/step) + 1
|
||||
source := make([]T, l, l)
|
||||
|
||||
for i := 0; i < l; i++ {
|
||||
source[i] = start + (T(i) * step)
|
||||
}
|
||||
|
||||
return FromSlice(source)
|
||||
}
|
||||
|
||||
// Distinct returns a stream that removes the duplicated items.
|
||||
func (s stream[T]) Distinct() stream[T] {
|
||||
source := make([]T, 0)
|
||||
|
||||
distinct := map[string]bool{}
|
||||
|
||||
for _, v := range s.source {
|
||||
// todo: performance issue
|
||||
k := hashKey(v)
|
||||
if _, ok := distinct[k]; !ok {
|
||||
distinct[k] = true
|
||||
source = append(source, v)
|
||||
}
|
||||
}
|
||||
|
||||
return FromSlice(source)
|
||||
}
|
||||
|
||||
func hashKey(data any) string {
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
encoder := gob.NewEncoder(buffer)
|
||||
err := encoder.Encode(data)
|
||||
if err != nil {
|
||||
panic("stream.hashKey: get hashkey failed")
|
||||
}
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// Filter returns a stream consisting of the elements of this stream that match the given predicate.
|
||||
func (s stream[T]) Filter(predicate func(item T) bool) stream[T] {
|
||||
source := make([]T, 0)
|
||||
|
||||
for _, v := range s.source {
|
||||
if predicate(v) {
|
||||
source = append(source, v)
|
||||
}
|
||||
}
|
||||
|
||||
return FromSlice(source)
|
||||
}
|
||||
|
||||
// Map returns a stream consisting of the elements of this stream that apply the given function to elements of stream.
|
||||
func (s stream[T]) Map(mapper func(item T) T) stream[T] {
|
||||
source := make([]T, s.Count(), s.Count())
|
||||
|
||||
for i, v := range s.source {
|
||||
source[i] = mapper(v)
|
||||
}
|
||||
|
||||
return FromSlice(source)
|
||||
}
|
||||
|
||||
// Peek returns a stream consisting of the elements of this stream, additionally performing the provided action on each element as elements are consumed from the resulting stream.
|
||||
func (s stream[T]) Peek(consumer func(item T)) stream[T] {
|
||||
for _, v := range s.source {
|
||||
consumer(v)
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// Skip returns a stream consisting of the remaining elements of this stream after discarding the first n elements of the stream.
|
||||
// If this stream contains fewer than n elements then an empty stream will be returned.
|
||||
func (s stream[T]) Skip(n int) stream[T] {
|
||||
if n <= 0 {
|
||||
return s
|
||||
}
|
||||
|
||||
source := make([]T, 0)
|
||||
l := len(s.source)
|
||||
|
||||
if n > l {
|
||||
return FromSlice(source)
|
||||
}
|
||||
|
||||
for i := n; i < l; i++ {
|
||||
source = append(source, s.source[i])
|
||||
}
|
||||
|
||||
return FromSlice(source)
|
||||
}
|
||||
|
||||
// Limit returns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length.
|
||||
func (s stream[T]) Limit(maxSize int) stream[T] {
|
||||
if s.source == nil {
|
||||
return s
|
||||
}
|
||||
|
||||
if maxSize < 0 {
|
||||
return FromSlice([]T{})
|
||||
}
|
||||
|
||||
source := make([]T, 0, maxSize)
|
||||
|
||||
for i := 0; i < len(s.source) && i < maxSize; i++ {
|
||||
source = append(source, s.source[i])
|
||||
}
|
||||
|
||||
return FromSlice(source)
|
||||
}
|
||||
|
||||
// AllMatch returns whether all elements of this stream match the provided predicate.
|
||||
func (s stream[T]) AllMatch(predicate func(item T) bool) bool {
|
||||
for _, v := range s.source {
|
||||
if !predicate(v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// AnyMatch returns whether any elements of this stream match the provided predicate.
|
||||
func (s stream[T]) AnyMatch(predicate func(item T) bool) bool {
|
||||
for _, v := range s.source {
|
||||
if predicate(v) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// NoneMatch returns whether no elements of this stream match the provided predicate.
|
||||
func (s stream[T]) NoneMatch(predicate func(item T) bool) bool {
|
||||
return !s.AnyMatch(predicate)
|
||||
}
|
||||
|
||||
// ForEach performs an action for each element of this stream.
|
||||
func (s stream[T]) ForEach(action func(item T)) {
|
||||
for _, v := range s.source {
|
||||
action(v)
|
||||
}
|
||||
}
|
||||
|
||||
// Reduce performs a reduction on the elements of this stream, using an associative accumulation function, and returns an Optional describing the reduced value, if any.
|
||||
func (s stream[T]) Reduce(init T, accumulator func(a, b T) T) T {
|
||||
for _, v := range s.source {
|
||||
init = accumulator(init, v)
|
||||
}
|
||||
|
||||
return init
|
||||
}
|
||||
|
||||
// Count returns the count of elements in the stream.
|
||||
func (s stream[T]) Count() int {
|
||||
return len(s.source)
|
||||
}
|
||||
|
||||
// ToSlice return the elements in the stream.
|
||||
func (s stream[T]) ToSlice() []T {
|
||||
return s.source
|
||||
}
|
||||
249
stream/stream_test.go
Normal file
249
stream/stream_test.go
Normal file
@@ -0,0 +1,249 @@
|
||||
package stream
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestOf(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestFromSlice")
|
||||
|
||||
stream := Of(1, 2, 3)
|
||||
assert.Equal([]int{1, 2, 3}, stream.ToSlice())
|
||||
}
|
||||
|
||||
func TestGenerate(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestFromSlice")
|
||||
|
||||
n := 0
|
||||
max := 4
|
||||
|
||||
generator := func() func() (int, bool) {
|
||||
return func() (int, bool) {
|
||||
n++
|
||||
return n, n < max
|
||||
}
|
||||
}
|
||||
|
||||
stream := Generate(generator)
|
||||
|
||||
assert.Equal([]int{1, 2, 3}, stream.ToSlice())
|
||||
}
|
||||
|
||||
func TestFromSlice(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestFromSlice")
|
||||
|
||||
stream := FromSlice([]int{1, 2, 3})
|
||||
|
||||
assert.Equal([]int{1, 2, 3}, stream.ToSlice())
|
||||
}
|
||||
|
||||
func TestFromChannel(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestFromChannel")
|
||||
|
||||
ch := make(chan int)
|
||||
go func() {
|
||||
for i := 1; i < 4; i++ {
|
||||
ch <- i
|
||||
}
|
||||
close(ch)
|
||||
}()
|
||||
|
||||
stream := FromChannel(ch)
|
||||
|
||||
assert.Equal([]int{1, 2, 3}, stream.ToSlice())
|
||||
}
|
||||
|
||||
func TestFromRange(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestFromRange")
|
||||
|
||||
s1 := FromRange(1, 5, 1)
|
||||
s2 := FromRange(1.1, 5.0, 1.0)
|
||||
|
||||
assert.Equal([]int{1, 2, 3, 4, 5}, s1.ToSlice())
|
||||
assert.Equal([]float64{1.1, 2.1, 3.1, 4.1}, s2.ToSlice())
|
||||
}
|
||||
|
||||
func TestStream_Distinct(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestStream_Distinct")
|
||||
|
||||
nums := FromSlice([]int{1, 2, 2, 3, 3, 3})
|
||||
distinctNums := nums.Distinct()
|
||||
|
||||
assert.Equal([]int{1, 2, 2, 3, 3, 3}, nums.ToSlice())
|
||||
assert.Equal([]int{1, 2, 3}, distinctNums.ToSlice())
|
||||
|
||||
type Person struct {
|
||||
Id string
|
||||
Name string
|
||||
Age uint
|
||||
}
|
||||
|
||||
people := []Person{
|
||||
{Id: "001", Name: "Tom", Age: 10},
|
||||
{Id: "001", Name: "Tom", Age: 10},
|
||||
{Id: "002", Name: "Jim", Age: 20},
|
||||
{Id: "003", Name: "Mike", Age: 30},
|
||||
}
|
||||
|
||||
stream := FromSlice(people)
|
||||
distinctStream := stream.Distinct()
|
||||
|
||||
// {[{001 Tom 10} {001 Tom 10} {002 Jim 20} {003 Mike 30}]}
|
||||
t.Log(stream)
|
||||
|
||||
// {[{001 Tom 10} {002 Jim 20} {003 Mike 30}]}
|
||||
t.Log(distinctStream)
|
||||
}
|
||||
|
||||
func TestStream_Filter(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestStream_Filter")
|
||||
|
||||
stream := FromSlice([]int{1, 2, 3, 4, 5})
|
||||
|
||||
isEven := func(n int) bool {
|
||||
return n%2 == 0
|
||||
}
|
||||
|
||||
even := stream.Filter(isEven)
|
||||
|
||||
assert.Equal([]int{2, 4}, even.ToSlice())
|
||||
}
|
||||
|
||||
func TestStream_Map(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestStream_Map")
|
||||
|
||||
stream := FromSlice([]int{1, 2, 3})
|
||||
|
||||
addOne := func(n int) int {
|
||||
return n + 1
|
||||
}
|
||||
|
||||
s := stream.Map(addOne)
|
||||
|
||||
assert.Equal([]int{2, 3, 4}, s.ToSlice())
|
||||
}
|
||||
|
||||
func TestStream_Peek(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestStream_Peek")
|
||||
|
||||
stream := FromSlice([]int{1, 2, 3, 4, 5, 6})
|
||||
|
||||
result := []string{}
|
||||
stream = stream.Filter(func(n int) bool {
|
||||
return n <= 3
|
||||
}).Peek(func(n int) {
|
||||
result = append(result, fmt.Sprint("current: ", n))
|
||||
})
|
||||
|
||||
assert.Equal([]int{1, 2, 3}, stream.ToSlice())
|
||||
assert.Equal([]string{
|
||||
"current: 1", "current: 2", "current: 3",
|
||||
}, result)
|
||||
}
|
||||
|
||||
func TestStream_Skip(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestStream_Peek")
|
||||
|
||||
stream := FromSlice([]int{1, 2, 3, 4, 5, 6})
|
||||
|
||||
s1 := stream.Skip(-1)
|
||||
s2 := stream.Skip(0)
|
||||
|
||||
assert.Equal([]int{1, 2, 3, 4, 5, 6}, s1.ToSlice())
|
||||
assert.Equal([]int{1, 2, 3, 4, 5, 6}, s2.ToSlice())
|
||||
}
|
||||
|
||||
func TestStream_Limit(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestStream_Limit")
|
||||
|
||||
stream := FromSlice([]int{1, 2, 3, 4, 5, 6})
|
||||
|
||||
s1 := stream.Limit(-1)
|
||||
s2 := stream.Limit(0)
|
||||
s3 := stream.Limit(1)
|
||||
s4 := stream.Limit(6)
|
||||
|
||||
assert.Equal([]int{}, s1.ToSlice())
|
||||
assert.Equal([]int{}, s2.ToSlice())
|
||||
assert.Equal([]int{1}, s3.ToSlice())
|
||||
assert.Equal([]int{1, 2, 3, 4, 5, 6}, s4.ToSlice())
|
||||
}
|
||||
|
||||
func TestStream_AllMatch(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestStream_AllMatch")
|
||||
|
||||
stream := FromSlice([]int{1, 2, 3, 4, 5, 6})
|
||||
|
||||
result1 := stream.AllMatch(func(item int) bool {
|
||||
return item > 0
|
||||
})
|
||||
|
||||
result2 := stream.AllMatch(func(item int) bool {
|
||||
return item > 1
|
||||
})
|
||||
|
||||
assert.Equal(true, result1)
|
||||
assert.Equal(false, result2)
|
||||
}
|
||||
|
||||
func TestStream_AnyMatch(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestStream_AnyMatch")
|
||||
|
||||
stream := FromSlice([]int{1, 2, 3})
|
||||
|
||||
result1 := stream.AnyMatch(func(item int) bool {
|
||||
return item > 3
|
||||
})
|
||||
|
||||
result2 := stream.AnyMatch(func(item int) bool {
|
||||
return item > 1
|
||||
})
|
||||
|
||||
assert.Equal(false, result1)
|
||||
assert.Equal(true, result2)
|
||||
}
|
||||
|
||||
func TestStream_NoneMatch(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestStream_NoneMatch")
|
||||
|
||||
stream := FromSlice([]int{1, 2, 3})
|
||||
|
||||
result1 := stream.NoneMatch(func(item int) bool {
|
||||
return item > 3
|
||||
})
|
||||
|
||||
result2 := stream.NoneMatch(func(item int) bool {
|
||||
return item > 1
|
||||
})
|
||||
|
||||
assert.Equal(true, result1)
|
||||
assert.Equal(false, result2)
|
||||
}
|
||||
|
||||
func TestStream_ForEach(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestStream_ForEach")
|
||||
|
||||
stream := FromSlice([]int{1, 2, 3})
|
||||
|
||||
result := 0
|
||||
stream.ForEach(func(item int) {
|
||||
result += item
|
||||
})
|
||||
|
||||
assert.Equal(6, result)
|
||||
}
|
||||
|
||||
func TestStream_Reduce(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestStream_Reduce")
|
||||
|
||||
stream := FromSlice([]int{1, 2, 3})
|
||||
|
||||
result := stream.Reduce(0, func(a, b int) int {
|
||||
return a + b
|
||||
})
|
||||
|
||||
assert.Equal(6, result)
|
||||
}
|
||||
@@ -283,7 +283,7 @@ func SplitEx(s, sep string, removeEmptyString bool) []string {
|
||||
}
|
||||
|
||||
// Substring returns a substring of the specified length starting at the specified offset position.
|
||||
// Play: Todo
|
||||
// Play: https://go.dev/play/p/q3sM6ehnPDp
|
||||
func Substring(s string, offset int, length uint) string {
|
||||
rs := []rune(s)
|
||||
size := len(rs)
|
||||
|
||||
@@ -3,10 +3,10 @@ package system
|
||||
import "fmt"
|
||||
|
||||
func ExampleSetOsEnv() {
|
||||
ok := SetOsEnv("foo", "abc")
|
||||
err := SetOsEnv("foo", "abc")
|
||||
result := GetOsEnv("foo")
|
||||
|
||||
fmt.Println(ok)
|
||||
fmt.Println(err)
|
||||
fmt.Println(result)
|
||||
// Output:
|
||||
// <nil>
|
||||
@@ -25,14 +25,14 @@ func ExampleGetOsEnv() {
|
||||
}
|
||||
|
||||
func ExampleRemoveOsEnv() {
|
||||
ok1 := SetOsEnv("foo", "abc")
|
||||
err1 := SetOsEnv("foo", "abc")
|
||||
result1 := GetOsEnv("foo")
|
||||
|
||||
ok2 := RemoveOsEnv("foo")
|
||||
err2 := RemoveOsEnv("foo")
|
||||
result2 := GetOsEnv("foo")
|
||||
|
||||
fmt.Println(ok1)
|
||||
fmt.Println(ok2)
|
||||
fmt.Println(err1)
|
||||
fmt.Println(err2)
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
@@ -49,9 +49,10 @@ func ExampleCompareOsEnv() {
|
||||
return
|
||||
}
|
||||
|
||||
result1 := CompareOsEnv("foo", "abc")
|
||||
result := CompareOsEnv("foo", "abc")
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
fmt.Println(result1)
|
||||
// Output:
|
||||
// true
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ var (
|
||||
chineseMobileMatcher *regexp.Regexp = regexp.MustCompile(`^1(?:3\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8\d|9\d)\d{8}$`)
|
||||
chineseIdMatcher *regexp.Regexp = regexp.MustCompile(`^[1-9]\d{5}(18|19|20|21|22)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$`)
|
||||
chineseMatcher *regexp.Regexp = regexp.MustCompile("[\u4e00-\u9fa5]")
|
||||
chinesePhoneMatcher *regexp.Regexp = regexp.MustCompile(`\d{3}-\d{8}|\d{4}-\d{7}`)
|
||||
chinesePhoneMatcher *regexp.Regexp = regexp.MustCompile(`\d{3}-\d{8}|\d{4}-\d{7}|\d{4}-\d{8}`)
|
||||
creditCardMatcher *regexp.Regexp = regexp.MustCompile(`^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11}|6[27][0-9]{14})$`)
|
||||
base64Matcher *regexp.Regexp = regexp.MustCompile(`^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$`)
|
||||
)
|
||||
|
||||
@@ -208,6 +208,7 @@ func TestIsChinesePhone(t *testing.T) {
|
||||
|
||||
assert.Equal(true, IsChinesePhone("010-32116675"))
|
||||
assert.Equal(true, IsChinesePhone("0464-8756213"))
|
||||
assert.Equal(true, IsChinesePhone("0731-82251545")) //长沙晚报电话
|
||||
assert.Equal(false, IsChinesePhone("123-87562"))
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user