mirror of
https://github.com/duke-git/lancet.git
synced 2026-03-01 00:35:28 +08:00
Compare commits
21 Commits
23e61f1acf
...
v2.3.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8120c4db78 | ||
|
|
0d0f213d36 | ||
|
|
41d4bbf0e3 | ||
|
|
fed1d5220e | ||
|
|
29a8318d6e | ||
|
|
3696213e5d | ||
|
|
90a3b87b67 | ||
|
|
a7b28ee864 | ||
|
|
f2823014f2 | ||
|
|
4181c42805 | ||
|
|
a09f5623d6 | ||
|
|
a9c75b081d | ||
|
|
db479ef1bc | ||
|
|
df8121fbbd | ||
|
|
0e7297cb97 | ||
|
|
2e619e48a3 | ||
|
|
3069acba4a | ||
|
|
fc43138a0e | ||
|
|
1e56e9964c | ||
|
|
f861e18bc3 | ||
|
|
e27df00fa8 |
72
README.md
72
README.md
@@ -4,7 +4,7 @@
|
|||||||
<br/>
|
<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://pkg.go.dev/github.com/duke-git/lancet/v2)
|
||||||
[](https://goreportcard.com/report/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)
|
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
||||||
@@ -506,9 +506,24 @@ import "github.com/duke-git/lancet/v2/datetime"
|
|||||||
- **<big>AddMinute</big>** : add or sub day to the time.
|
- **<big>AddMinute</big>** : add or sub day to the time.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/datetime.md#AddMinute)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/datetime.md#AddMinute)]
|
||||||
[[play](https://go.dev/play/p/nT1heB1KUUK)]
|
[[play](https://go.dev/play/p/nT1heB1KUUK)]
|
||||||
|
- **<big>AddWeek</big>** : add or sub week to time.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/datetime.md#AddWeek)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>AddMonth</big>** : add or sub months to time.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/datetime.md#AddMonth)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
- **<big>AddYear</big>** : add or sub year to the time.
|
- **<big>AddYear</big>** : add or sub year to the time.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/datetime.md#AddYear)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/datetime.md#AddYear)]
|
||||||
[[play](https://go.dev/play/p/MqW2ujnBx10)]
|
[[play](https://go.dev/play/p/MqW2ujnBx10)]
|
||||||
|
- **<big>AddDaySafe</big>** : add or sub days to the time and ensure that the returned date does not exceed the valid date of the target year and month.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/datetime.md#AddDaySafe)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>AddMonthSafe</big>** : add or sub months to the time and ensure that the returned date does not exceed the valid date of the target year and month.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/datetime.md#AddMonthSafe)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>AddYearSafe</big>** : Add or sub years to the time and ensure that the returned date does not exceed the valid date of the target year and month.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/datetime.md#AddYearSafe)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
- **<big>BeginOfMinute</big>** : return the date time at the begin of minute of specific date.
|
- **<big>BeginOfMinute</big>** : return the date time at the begin of minute of specific date.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/datetime.md#BeginOfMinute)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/datetime.md#BeginOfMinute)]
|
||||||
[[play](https://go.dev/play/p/ieOLVJ9CiFT)]
|
[[play](https://go.dev/play/p/ieOLVJ9CiFT)]
|
||||||
@@ -680,6 +695,45 @@ import optional "github.com/duke-git/lancet/v2/datastructure/optional"
|
|||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/datastructure/optional.md)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/datastructure/optional.md)]
|
||||||
|
|
||||||
|
|
||||||
|
<h3 id="eventbus"> 9. EventBus is an event bus used for handling events within an application. <a href="#index">Index</a></h3>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 函数列表:
|
||||||
|
|
||||||
|
- **<big>NewEventBus</big>** : Create an EventBus instance.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/eventbus.md#NewEventBus)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>Subscribe</big>** : subscribes to an event with a specific event topic and listener function.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/eventbus.md#Subscribe)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>Unsubscribe</big>** : unsubscribes from an event with a specific event topic and listener function.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/eventbus.md#Unsubscribe)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>Publish</big>** : publishes an event with a specific event topic and data payload.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/eventbus.md#Publish)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>ClearListeners</big>** : clears all the listeners.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/eventbus.md#ClearListeners)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>ClearListenersByTopic</big>** : clears all the listeners by topic.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/eventbus.md#ClearListenersByTopic)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>GetListenersCount</big>** : returns the number of listeners for a specific event topic.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/eventbus.md#GetListenersCount)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>GetAllListenersCount</big>** : returns the total number of all listeners.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/eventbus.md#GetAllListenersCount)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>GetEvents</big>** : returns all the events topics.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/eventbus.md#GetEvents)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>SetErrorHandler</big>** : sets the error handler function.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/eventbus.md#SetErrorHandler)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
|
||||||
<h3 id="fileutil"> 9. Fileutil package implements some basic functions for file operations. <a href="#index">index</a></h3>
|
<h3 id="fileutil"> 9. Fileutil package implements some basic functions for file operations. <a href="#index">index</a></h3>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -1423,6 +1477,9 @@ import "github.com/duke-git/lancet/v2/slice"
|
|||||||
- **<big>EqualWith</big>** : checks if two slices are equal with comparator func.
|
- **<big>EqualWith</big>** : checks if two slices are equal with comparator func.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#EqualWith)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#EqualWith)]
|
||||||
[[play](https://go.dev/play/p/b9iygtgsHI1)]
|
[[play](https://go.dev/play/p/b9iygtgsHI1)]
|
||||||
|
- **<big>EqualUnordered</big>** : Checks if two slices are equal: the same length and all elements value are equal (unordered).
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#EqualUnordered)]
|
||||||
|
[[play](todo)]
|
||||||
- **<big>Every</big>** : return true if all of the values in the slice pass the predicate function.
|
- **<big>Every</big>** : return true if all of the values in the slice pass the predicate function.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#Every)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#Every)]
|
||||||
[[play](https://go.dev/play/p/R8U6Sl-j8cD)]
|
[[play](https://go.dev/play/p/R8U6Sl-j8cD)]
|
||||||
@@ -1522,6 +1579,9 @@ import "github.com/duke-git/lancet/v2/slice"
|
|||||||
- **<big>Shuffle</big>** : shuffle the slice.
|
- **<big>Shuffle</big>** : shuffle the slice.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#Shuffle)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#Shuffle)]
|
||||||
[[play](https://go.dev/play/p/YHvhnWGU3Ge)]
|
[[play](https://go.dev/play/p/YHvhnWGU3Ge)]
|
||||||
|
- **<big>ShuffleCopy</big>** : return a new slice with elements shuffled.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#ShuffleCopy)]
|
||||||
|
[[play](todo)]
|
||||||
- **<big>IsAscending</big>** : Checks if a slice is ascending order.
|
- **<big>IsAscending</big>** : Checks if a slice is ascending order.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#IsAscending)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#IsAscending)]
|
||||||
[[play](https://go.dev/play/p/9CtsFjet4SH)]
|
[[play](https://go.dev/play/p/9CtsFjet4SH)]
|
||||||
@@ -1668,6 +1728,9 @@ import "github.com/duke-git/lancet/v2/stream"
|
|||||||
- **<big>Reverse</big>** : returns a stream whose elements are reverse order of given stream.
|
- **<big>Reverse</big>** : returns a stream whose elements are reverse order of given stream.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/stream.md#Reverse)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/stream.md#Reverse)]
|
||||||
[[play](https://go.dev/play/p/A8_zkJnLHm4)]
|
[[play](https://go.dev/play/p/A8_zkJnLHm4)]
|
||||||
|
- **<big>ReverseCopy</big>** : returns a new slice of element order is reversed to the given slice.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/stream.md#ReverseCopy)]
|
||||||
|
[[play](todo)]
|
||||||
- **<big>Range</big>** : returns a stream whose elements are in the range from start(included) to end(excluded) original stream.
|
- **<big>Range</big>** : returns a stream whose elements are in the range from start(included) to end(excluded) original stream.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/stream.md#Range)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/stream.md#Range)]
|
||||||
[[play](https://go.dev/play/p/indZY5V2f4j)]
|
[[play](https://go.dev/play/p/indZY5V2f4j)]
|
||||||
@@ -1897,7 +1960,9 @@ import "github.com/duke-git/lancet/v2/strutil"
|
|||||||
- **<big>ExtractContent</big>** : extracts the content between the start and end strings in the source string.
|
- **<big>ExtractContent</big>** : extracts the content between the start and end strings in the source string.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/strutil.md#ExtractContent)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/strutil.md#ExtractContent)]
|
||||||
[[play](https://go.dev/play/p/Ay9UIk7Rum9)]
|
[[play](https://go.dev/play/p/Ay9UIk7Rum9)]
|
||||||
|
- **<big>FindAllOccurrences</big>** : Returns the positions of all occurrences of a substring in a string.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/strutil.md#FindAllOccurrences)]
|
||||||
|
[[play](todo)]
|
||||||
|
|
||||||
<h3 id="system"> 22. System package contain some functions about os, runtime, shell command. <a href="#index">index</a></h3>
|
<h3 id="system"> 22. System package contain some functions about os, runtime, shell command. <a href="#index">index</a></h3>
|
||||||
|
|
||||||
@@ -2151,6 +2216,9 @@ import "github.com/duke-git/lancet/v2/validator"
|
|||||||
- **<big>IsIpV6</big>** : check if the string is ipv6.
|
- **<big>IsIpV6</big>** : check if the string is ipv6.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsIpV6)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsIpV6)]
|
||||||
[[play](https://go.dev/play/p/AHA0r0AzIdC)]
|
[[play](https://go.dev/play/p/AHA0r0AzIdC)]
|
||||||
|
- **<big>IsIpPort</big>** : check if the string is ip:port.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsIpPort)]
|
||||||
|
[[play](todo)]
|
||||||
- **<big>IsStrongPassword</big>** : check if the string is strong password.
|
- **<big>IsStrongPassword</big>** : check if the string is strong password.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsStrongPassword)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsStrongPassword)]
|
||||||
[[play](https://go.dev/play/p/QHdVcSQ3uDg)]
|
[[play](https://go.dev/play/p/QHdVcSQ3uDg)]
|
||||||
|
|||||||
106
README_zh-CN.md
106
README_zh-CN.md
@@ -4,7 +4,7 @@
|
|||||||
<br/>
|
<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://pkg.go.dev/github.com/duke-git/lancet/v2)
|
||||||
[](https://goreportcard.com/report/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)
|
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
||||||
@@ -507,9 +507,24 @@ import "github.com/duke-git/lancet/v2/datetime"
|
|||||||
- **<big>AddMinute</big>** : 将日期加/减分钟数。
|
- **<big>AddMinute</big>** : 将日期加/减分钟数。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/datetime.md#AddMinute)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/datetime.md#AddMinute)]
|
||||||
[[play](https://go.dev/play/p/nT1heB1KUUK)]
|
[[play](https://go.dev/play/p/nT1heB1KUUK)]
|
||||||
|
- **<big>AddWeek</big>** : 将日期加/减星期数.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/datetime.md#AddWeek)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>AddMonth</big>** : 将日期加/减月数.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/datetime.md#AddMonth)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
- **<big>AddYear</big>** : 将日期加/减分年数。
|
- **<big>AddYear</big>** : 将日期加/减分年数。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/datetime.md#AddYear)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/datetime.md#AddYear)]
|
||||||
[[play](https://go.dev/play/p/MqW2ujnBx10)]
|
[[play](https://go.dev/play/p/MqW2ujnBx10)]
|
||||||
|
- **<big>AddDaySafe</big>** : 增加/减少指定的天数,并确保日期是有效日期。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/datetime.md#AddDaySafe)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>AddMonthSafe</big>** : 增加/减少指定的月份,并确保日期是有效日期。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/datetime.md#AddMonthSafe)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>AddYearSafe</big>** : 增加/减少指定的年份,并确保日期是有效日期。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/datetime.md#AddYearSafe)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
- **<big>BeginOfMinute</big>** : 返回指定时间的分钟开始时间。
|
- **<big>BeginOfMinute</big>** : 返回指定时间的分钟开始时间。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/datetime.md#BeginOfMinute)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/datetime.md#BeginOfMinute)]
|
||||||
[[play](https://go.dev/play/p/ieOLVJ9CiFT)]
|
[[play](https://go.dev/play/p/ieOLVJ9CiFT)]
|
||||||
@@ -679,7 +694,46 @@ import hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
|||||||
- **<big>Hashmap</big>** : 哈希映射。
|
- **<big>Hashmap</big>** : 哈希映射。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/datastructure/hashmap.md)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/datastructure/hashmap.md)]
|
||||||
|
|
||||||
<h3 id="fileutil"> 9. fileutil 包含文件基本操作。 <a href="#index">回到目录</a></h3>
|
<h3 id="eventbus"> 9. EventbBus是一个事件总线,用于在应用程序中处理事件。 <a href="#index">回到目录</a></h3>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 函数列表:
|
||||||
|
|
||||||
|
- **<big>NewEventBus</big>** : 创建EventBus实例。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/eventbus.md#NewEventBus)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>Subscribe</big>** : 订阅具有特定事件主题和监听函数的事件。支持异步,事件优先级,事件过滤器。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/eventbus.md#Subscribe)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>Unsubscribe</big>** : 取消订阅具有特定事件主题的事件。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/eventbus.md#Unsubscribe)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>Publish</big>** : 发布一个带有特定事件主题和数据负载的事件。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/eventbus.md#Publish)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>ClearListeners</big>** : 清空所有事件监听器。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/eventbus.md#ClearListeners)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>ClearListenersByTopic</big>** : 清空特定事件监听器。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/eventbus.md#ClearListenersByTopic)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>GetListenersCount</big>** : 获取特定事件的监听器数量。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/eventbus.md#GetListenersCount)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>GetAllListenersCount</big>** : 获取所有事件的监听器数量。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/eventbus.md#GetAllListenersCount)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>GetEvents</big>** : 获取所有事件的topic。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/eventbus.md#GetEvents)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
- **<big>SetErrorHandler</big>** : 设置事件的错误处理函数。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/eventbus.md#SetErrorHandler)]
|
||||||
|
[[play](https://go.dev/play/p/todo)]
|
||||||
|
|
||||||
|
<h3 id="fileutil"> 10. fileutil 包含文件基本操作。 <a href="#index">回到目录</a></h3>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/fileutil"
|
import "github.com/duke-git/lancet/v2/fileutil"
|
||||||
@@ -779,7 +833,7 @@ import "github.com/duke-git/lancet/v2/fileutil"
|
|||||||
[[play](https://go.dev/play/p/iLRrDBhE38E)]
|
[[play](https://go.dev/play/p/iLRrDBhE38E)]
|
||||||
|
|
||||||
|
|
||||||
<h3 id="formatter"> 10. formatter 格式化器包含一些数据格式化处理方法。 <a href="#index">回到目录</a></h3>
|
<h3 id="formatter"> 11. formatter 格式化器包含一些数据格式化处理方法。 <a href="#index">回到目录</a></h3>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/formatter"
|
import "github.com/duke-git/lancet/v2/formatter"
|
||||||
@@ -809,7 +863,7 @@ import "github.com/duke-git/lancet/v2/formatter"
|
|||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/formatter.md#ParseBinaryBytes)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/formatter.md#ParseBinaryBytes)]
|
||||||
[[play](https://go.dev/play/p/69v1tTT62x8)]
|
[[play](https://go.dev/play/p/69v1tTT62x8)]
|
||||||
|
|
||||||
<h3 id="function"> 11. function 函数包控制函数执行流程,包含部分函数式编程。 <a href="#index">回到目录</a></h3>
|
<h3 id="function"> 12. function 函数包控制函数执行流程,包含部分函数式编程。 <a href="#index">回到目录</a></h3>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/function"
|
import "github.com/duke-git/lancet/v2/function"
|
||||||
@@ -874,7 +928,7 @@ import "github.com/duke-git/lancet/v2/function"
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h3 id="maputil"> 12. maputil 包括一些操作 map 的函数。 <a href="#index">回到目录</a></h3>
|
<h3 id="maputil"> 13. maputil 包括一些操作 map 的函数。 <a href="#index">回到目录</a></h3>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/maputil"
|
import "github.com/duke-git/lancet/v2/maputil"
|
||||||
@@ -1045,7 +1099,7 @@ import "github.com/duke-git/lancet/v2/maputil"
|
|||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/maputil.md#GetOrDefault)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/maputil.md#GetOrDefault)]
|
||||||
[[play](https://go.dev/play/p/99QjSYSBdiM)]
|
[[play](https://go.dev/play/p/99QjSYSBdiM)]
|
||||||
|
|
||||||
<h3 id="mathutil"> 13. mathutil 包实现了一些数学计算的函数。 <a href="#index">回到目录</a></h3>
|
<h3 id="mathutil"> 14. mathutil 包实现了一些数学计算的函数。 <a href="#index">回到目录</a></h3>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/mathutil"
|
import "github.com/duke-git/lancet/v2/mathutil"
|
||||||
@@ -1156,7 +1210,7 @@ import "github.com/duke-git/lancet/v2/mathutil"
|
|||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/mathutil.md#Combination)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/mathutil.md#Combination)]
|
||||||
[[play](https://go.dev/play/p/ENFQRDQUFi9)]
|
[[play](https://go.dev/play/p/ENFQRDQUFi9)]
|
||||||
|
|
||||||
<h3 id="netutil"> 14. netutil 网络包支持获取 ip 地址,发送 http 请求。 <a href="#index">回到目录</a></h3>
|
<h3 id="netutil"> 15. netutil 网络包支持获取 ip 地址,发送 http 请求。 <a href="#index">回到目录</a></h3>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/netutil"
|
import "github.com/duke-git/lancet/v2/netutil"
|
||||||
@@ -1229,7 +1283,7 @@ import "github.com/duke-git/lancet/v2/netutil"
|
|||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/netutil.md#IsTelnetConnected)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/netutil.md#IsTelnetConnected)]
|
||||||
[[play](https://go.dev/play/p/yiLCGtQv_ZG)]
|
[[play](https://go.dev/play/p/yiLCGtQv_ZG)]
|
||||||
|
|
||||||
<h3 id="pointer"> 15. pointer 包支持一些指针类型的操作。 <a href="#index">回到目录</a></h3>
|
<h3 id="pointer"> 16. pointer 包支持一些指针类型的操作。 <a href="#index">回到目录</a></h3>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/pointer"
|
import "github.com/duke-git/lancet/v2/pointer"
|
||||||
@@ -1253,7 +1307,7 @@ import "github.com/duke-git/lancet/v2/pointer"
|
|||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/pointer.md#UnwrapOrDefault)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/pointer.md#UnwrapOrDefault)]
|
||||||
[[play](https://go.dev/play/p/ZnGIHf8_o4E)]
|
[[play](https://go.dev/play/p/ZnGIHf8_o4E)]
|
||||||
|
|
||||||
<h3 id="random"> 16. random 随机数生成器包,可以生成随机[]bytes, int, string。 <a href="#index">回到目录</a></h3>
|
<h3 id="random"> 17. random 随机数生成器包,可以生成随机[]bytes, int, string。 <a href="#index">回到目录</a></h3>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/random"
|
import "github.com/duke-git/lancet/v2/random"
|
||||||
@@ -1319,7 +1373,7 @@ import "github.com/duke-git/lancet/v2/random"
|
|||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/random.md#RandNumberOfLength)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/random.md#RandNumberOfLength)]
|
||||||
[[play](https://go.dev/play/p/oyZbuV7bu7b)]
|
[[play](https://go.dev/play/p/oyZbuV7bu7b)]
|
||||||
|
|
||||||
<h3 id="retry"> 17. retry 重试执行函数直到函数运行成功或被 context cancel。 <a href="#index">回到目录</a></h3>
|
<h3 id="retry"> 18. retry 重试执行函数直到函数运行成功或被 context cancel。 <a href="#index">回到目录</a></h3>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/retry"
|
import "github.com/duke-git/lancet/v2/retry"
|
||||||
@@ -1353,7 +1407,7 @@ import "github.com/duke-git/lancet/v2/retry"
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h3 id="slice"> 18. slice 包含操作切片的方法集合。 <a href="#index">回到目录</a></h3>
|
<h3 id="slice"> 19. slice 包含操作切片的方法集合。 <a href="#index">回到目录</a></h3>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/slice"
|
import "github.com/duke-git/lancet/v2/slice"
|
||||||
@@ -1421,6 +1475,9 @@ import "github.com/duke-git/lancet/v2/slice"
|
|||||||
- **<big>EqualWith</big>** : 检查两个切片是否相等,相等条件:对两个切片的元素调用比较函数 comparator,返回 true。
|
- **<big>EqualWith</big>** : 检查两个切片是否相等,相等条件:对两个切片的元素调用比较函数 comparator,返回 true。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#EqualWith)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#EqualWith)]
|
||||||
[[play](https://go.dev/play/p/b9iygtgsHI1)]
|
[[play](https://go.dev/play/p/b9iygtgsHI1)]
|
||||||
|
- **<big>EqualUnordered</big>** : 检查两个切片是否相等,元素数量相同,值相等,不考虑元素顺序。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#EqualUnordered)]
|
||||||
|
[[play](todo)]
|
||||||
- **<big>Every</big>** : 如果切片中的所有值都通过谓词函数,则返回 true。
|
- **<big>Every</big>** : 如果切片中的所有值都通过谓词函数,则返回 true。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#Every)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#Every)]
|
||||||
[[play](https://go.dev/play/p/R8U6Sl-j8cD)]
|
[[play](https://go.dev/play/p/R8U6Sl-j8cD)]
|
||||||
@@ -1496,6 +1553,9 @@ import "github.com/duke-git/lancet/v2/slice"
|
|||||||
- **<big>Reverse</big>** : 反转切片中的元素顺序。
|
- **<big>Reverse</big>** : 反转切片中的元素顺序。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#Reverse)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#Reverse)]
|
||||||
[[play](https://go.dev/play/p/8uI8f1lwNrQ)]
|
[[play](https://go.dev/play/p/8uI8f1lwNrQ)]
|
||||||
|
- **<big>ReverseCopy</big>** : 反转切片中的元素顺序, 不改变原slice。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/stream.md#ReverseCopy)]
|
||||||
|
[[play](todo)]
|
||||||
- **<big>Reduce<sup>deprecated</sup></big>** : 将切片中的元素依次运行 iteratee 函数,返回运行结果。(废弃:建议使用 ReduceBy)
|
- **<big>Reduce<sup>deprecated</sup></big>** : 将切片中的元素依次运行 iteratee 函数,返回运行结果。(废弃:建议使用 ReduceBy)
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#Reduce)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#Reduce)]
|
||||||
[[play](https://go.dev/play/p/_RfXJJWIsIm)]
|
[[play](https://go.dev/play/p/_RfXJJWIsIm)]
|
||||||
@@ -1520,6 +1580,9 @@ import "github.com/duke-git/lancet/v2/slice"
|
|||||||
- **<big>Shuffle</big>** : 随机打乱切片中的元素顺序。
|
- **<big>Shuffle</big>** : 随机打乱切片中的元素顺序。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#Shuffle)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#Shuffle)]
|
||||||
[[play](https://go.dev/play/p/YHvhnWGU3Ge)]
|
[[play](https://go.dev/play/p/YHvhnWGU3Ge)]
|
||||||
|
- **<big>ShuffleCopy</big>** : 随机打乱切片中的元素顺序, 不改变原切片。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#ShuffleCopy)]
|
||||||
|
[[play](todo)]
|
||||||
- **<big>IsAscending</big>** : 检查切片元素是否按升序排列。
|
- **<big>IsAscending</big>** : 检查切片元素是否按升序排列。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#IsAscending)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#IsAscending)]
|
||||||
[[play](https://go.dev/play/p/9CtsFjet4SH)]
|
[[play](https://go.dev/play/p/9CtsFjet4SH)]
|
||||||
@@ -1615,7 +1678,7 @@ import "github.com/duke-git/lancet/v2/slice"
|
|||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#ConcatBy)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#ConcatBy)]
|
||||||
[[play](https://go.dev/play/p/6QcUpcY4UMW)]
|
[[play](https://go.dev/play/p/6QcUpcY4UMW)]
|
||||||
|
|
||||||
<h3 id="stream"> 19. stream 流,该包仅验证简单的 stream 实现,功能有限。 <a href="#index">回到目录</a></h3>
|
<h3 id="stream"> 20. stream 流,该包仅验证简单的 stream 实现,功能有限。 <a href="#index">回到目录</a></h3>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/stream"
|
import "github.com/duke-git/lancet/v2/stream"
|
||||||
@@ -1711,7 +1774,7 @@ import "github.com/duke-git/lancet/v2/stream"
|
|||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/stream.md#LastIndexOf)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/stream.md#LastIndexOf)]
|
||||||
[[play](https://go.dev/play/p/CjeoNw2eac_G)]
|
[[play](https://go.dev/play/p/CjeoNw2eac_G)]
|
||||||
|
|
||||||
<h3 id="structs"> 20. structs 提供操作 struct, tag, field 的相关函数。 <a href="#index">回到目录</a></h3>
|
<h3 id="structs"> 21. structs 提供操作 struct, tag, field 的相关函数。 <a href="#index">回到目录</a></h3>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/structs"
|
import "github.com/duke-git/lancet/v2/structs"
|
||||||
@@ -1748,7 +1811,7 @@ import "github.com/duke-git/lancet/v2/structs"
|
|||||||
- **<big>IsTargetType</big>** : 判断属性是否是目标类型。
|
- **<big>IsTargetType</big>** : 判断属性是否是目标类型。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#IsTargetType)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#IsTargetType)]
|
||||||
|
|
||||||
<h3 id="strutil"> 21. strutil 包含字符串处理的相关函数。 <a href="#index">回到目录</a></h3>
|
<h3 id="strutil"> 22. strutil 包含字符串处理的相关函数。 <a href="#index">回到目录</a></h3>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/strutil"
|
import "github.com/duke-git/lancet/v2/strutil"
|
||||||
@@ -1897,8 +1960,12 @@ import "github.com/duke-git/lancet/v2/strutil"
|
|||||||
- **<big>ExtractContent</big>** : 提取两个标记之间的内容。
|
- **<big>ExtractContent</big>** : 提取两个标记之间的内容。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/strutil.md#ExtractContent)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/strutil.md#ExtractContent)]
|
||||||
[[play](https://go.dev/play/p/Ay9UIk7Rum9)]
|
[[play](https://go.dev/play/p/Ay9UIk7Rum9)]
|
||||||
|
- **<big>FindAllOccurrences</big>** : 返回子字符串在字符串中所有出现的位置。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/strutil.md#FindAllOccurrences)]
|
||||||
|
[[play](todo)]
|
||||||
|
|
||||||
<h3 id="system"> 22. system 包含 os, runtime, shell command 的相关函数。 <a href="#index">回到目录</a></h3>
|
|
||||||
|
<h3 id="system"> 23. system 包含 os, runtime, shell command 的相关函数。 <a href="#index">回到目录</a></h3>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/system"
|
import "github.com/duke-git/lancet/v2/system"
|
||||||
@@ -1948,7 +2015,7 @@ import "github.com/duke-git/lancet/v2/system"
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h3 id="tuple"> 23. Tuple 包实现一个元组数据类型。 <a href="#index">回到目录</a></h3>
|
<h3 id="tuple"> 24. Tuple 包实现一个元组数据类型。 <a href="#index">回到目录</a></h3>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/tuple"
|
import "github.com/duke-git/lancet/v2/tuple"
|
||||||
@@ -2065,7 +2132,7 @@ import "github.com/duke-git/lancet/v2/tuple"
|
|||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/tuple.md#Unzip10)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/tuple.md#Unzip10)]
|
||||||
[[play](https://go.dev/play/p/-taQB6Wfre_z)]
|
[[play](https://go.dev/play/p/-taQB6Wfre_z)]
|
||||||
|
|
||||||
<h3 id="validator"> 24. validator 验证器包,包含常用字符串格式验证函数。 <a href="#index">回到目录</a></h3>
|
<h3 id="validator"> 25. validator 验证器包,包含常用字符串格式验证函数。 <a href="#index">回到目录</a></h3>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/validator"
|
import "github.com/duke-git/lancet/v2/validator"
|
||||||
@@ -2151,6 +2218,9 @@ import "github.com/duke-git/lancet/v2/validator"
|
|||||||
- **<big>IsIpV6</big>** : 验证字符串是否是ipv6地址。
|
- **<big>IsIpV6</big>** : 验证字符串是否是ipv6地址。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/validator.md#IsIpV6)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/validator.md#IsIpV6)]
|
||||||
[[play](https://go.dev/play/p/AHA0r0AzIdC)]
|
[[play](https://go.dev/play/p/AHA0r0AzIdC)]
|
||||||
|
- **<big>IsIpPort</big>** : 检查字符串是否是ip:port格式。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/validator.md#IsIpPort)]
|
||||||
|
[[play](todo)]
|
||||||
- **<big>IsStrongPassword</big>** : 验证字符串是否是强密码:(字母+数字+特殊字符)。
|
- **<big>IsStrongPassword</big>** : 验证字符串是否是强密码:(字母+数字+特殊字符)。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/validator.md#IsStrongPassword)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/validator.md#IsStrongPassword)]
|
||||||
[[play](https://go.dev/play/p/QHdVcSQ3uDg)]
|
[[play](https://go.dev/play/p/QHdVcSQ3uDg)]
|
||||||
@@ -2200,7 +2270,7 @@ import "github.com/duke-git/lancet/v2/validator"
|
|||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/validator.md#IsChinaUnionPay)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/validator.md#IsChinaUnionPay)]
|
||||||
[[play](https://go.dev/play/p/yafpdxLiymu)]
|
[[play](https://go.dev/play/p/yafpdxLiymu)]
|
||||||
|
|
||||||
<h3 id="xerror"> 25. xerror 包实现一些错误处理函数。 <a href="#index">回到目录</a></h3>
|
<h3 id="xerror"> 26. xerror 包实现一些错误处理函数。 <a href="#index">回到目录</a></h3>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/xerror"
|
import "github.com/duke-git/lancet/v2/xerror"
|
||||||
|
|||||||
@@ -157,10 +157,10 @@ func (c *Channel[T]) Tee(ctx context.Context, in <-chan T) (<-chan T, <-chan T)
|
|||||||
// Play: https://go.dev/play/p/qmWSy1NVF-Y
|
// Play: https://go.dev/play/p/qmWSy1NVF-Y
|
||||||
func (c *Channel[T]) Bridge(ctx context.Context, chanStream <-chan <-chan T) <-chan T {
|
func (c *Channel[T]) Bridge(ctx context.Context, chanStream <-chan <-chan T) <-chan T {
|
||||||
valStream := make(chan T)
|
valStream := make(chan T)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer close(valStream)
|
defer close(valStream)
|
||||||
|
wg := sync.WaitGroup{}
|
||||||
|
defer wg.Wait()
|
||||||
for {
|
for {
|
||||||
var stream <-chan T
|
var stream <-chan T
|
||||||
select {
|
select {
|
||||||
@@ -169,19 +169,22 @@ func (c *Channel[T]) Bridge(ctx context.Context, chanStream <-chan <-chan T) <-c
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
stream = maybeStream
|
stream = maybeStream
|
||||||
|
wg.Add(1)
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for val := range c.OrDone(ctx, stream) {
|
go func() {
|
||||||
select {
|
defer wg.Done()
|
||||||
case valStream <- val:
|
for val := range c.OrDone(ctx, stream) {
|
||||||
case <-ctx.Done():
|
select {
|
||||||
|
case valStream <- val:
|
||||||
|
case <-ctx.Done():
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return valStream
|
return valStream
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -168,7 +168,8 @@ func ExampleChannel_Tee() {
|
|||||||
func ExampleChannel_Bridge() {
|
func ExampleChannel_Bridge() {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
m1 := make(map[int]int)
|
||||||
|
m2 := make(map[int]int)
|
||||||
c := NewChannel[int]()
|
c := NewChannel[int]()
|
||||||
genVals := func() <-chan <-chan int {
|
genVals := func() <-chan <-chan int {
|
||||||
out := make(chan (<-chan int))
|
out := make(chan (<-chan int))
|
||||||
@@ -177,6 +178,7 @@ func ExampleChannel_Bridge() {
|
|||||||
for i := 1; i <= 5; i++ {
|
for i := 1; i <= 5; i++ {
|
||||||
stream := make(chan int, 1)
|
stream := make(chan int, 1)
|
||||||
stream <- i
|
stream <- i
|
||||||
|
m1[i]++
|
||||||
close(stream)
|
close(stream)
|
||||||
out <- stream
|
out <- stream
|
||||||
}
|
}
|
||||||
@@ -185,12 +187,15 @@ func ExampleChannel_Bridge() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for v := range c.Bridge(ctx, genVals()) {
|
for v := range c.Bridge(ctx, genVals()) {
|
||||||
fmt.Println(v)
|
m2[v]++
|
||||||
|
}
|
||||||
|
for k, v := range m1 {
|
||||||
|
fmt.Println(m2[k] == v)
|
||||||
}
|
}
|
||||||
// Output:
|
// Output:
|
||||||
// 1
|
// true
|
||||||
// 2
|
// true
|
||||||
// 3
|
// true
|
||||||
// 4
|
// true
|
||||||
// 5
|
// true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -169,7 +169,8 @@ func TestTee(t *testing.T) {
|
|||||||
func TestBridge(t *testing.T) {
|
func TestBridge(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
assert := internal.NewAssert(t, "TestBridge")
|
assert := internal.NewAssert(t, "TestBridge")
|
||||||
|
m1 := make(map[int]int)
|
||||||
|
m2 := make(map[int]int)
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
@@ -181,6 +182,7 @@ func TestBridge(t *testing.T) {
|
|||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
stream := make(chan int, 1)
|
stream := make(chan int, 1)
|
||||||
stream <- i
|
stream <- i
|
||||||
|
m1[i]++
|
||||||
close(stream)
|
close(stream)
|
||||||
chanStream <- stream
|
chanStream <- stream
|
||||||
}
|
}
|
||||||
@@ -188,9 +190,11 @@ func TestBridge(t *testing.T) {
|
|||||||
return chanStream
|
return chanStream
|
||||||
}
|
}
|
||||||
|
|
||||||
index := 0
|
|
||||||
for val := range c.Bridge(ctx, genVals()) {
|
for val := range c.Bridge(ctx, genVals()) {
|
||||||
assert.Equal(index, val)
|
m2[val]++
|
||||||
index++
|
}
|
||||||
|
|
||||||
|
for k, v := range m1 {
|
||||||
|
assert.Equal(m2[k], v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,6 +108,13 @@ func ToString(value any) string {
|
|||||||
if value == nil {
|
if value == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
rv := reflect.ValueOf(value)
|
||||||
|
if rv.Kind() == reflect.Ptr {
|
||||||
|
if rv.IsNil() {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return ToString(rv.Elem().Interface())
|
||||||
|
}
|
||||||
|
|
||||||
switch val := value.(type) {
|
switch val := value.(type) {
|
||||||
case float32:
|
case float32:
|
||||||
|
|||||||
@@ -142,13 +142,24 @@ func TestToString(t *testing.T) {
|
|||||||
}
|
}
|
||||||
aStruct := TestStruct{Name: "TestStruct"}
|
aStruct := TestStruct{Name: "TestStruct"}
|
||||||
|
|
||||||
|
i32Val := int32(123)
|
||||||
|
i64Val := int64(123)
|
||||||
|
iZeroVal := 0
|
||||||
|
fVal := 12.3
|
||||||
|
sVal := "abc"
|
||||||
|
var iNilPointer *int
|
||||||
|
var sNilPointer *string
|
||||||
|
|
||||||
cases := []any{
|
cases := []any{
|
||||||
"", nil,
|
"", nil,
|
||||||
int(0), int8(1), int16(-1), int32(123), int64(123),
|
int(0), int8(1), int16(-1), int32(123), int64(123),
|
||||||
uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
|
uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
|
||||||
float64(12.3), float32(12.3),
|
float64(12.3), float32(12.3),
|
||||||
true, false,
|
true, false,
|
||||||
[]int{1, 2, 3}, aMap, aStruct, []byte{104, 101, 108, 108, 111}}
|
[]int{1, 2, 3}, aMap, aStruct, []byte{104, 101, 108, 108, 111},
|
||||||
|
&i32Val, &i64Val, &fVal, &sVal, &aStruct, iNilPointer, sNilPointer,
|
||||||
|
&iZeroVal,
|
||||||
|
}
|
||||||
|
|
||||||
expected := []string{
|
expected := []string{
|
||||||
"", "",
|
"", "",
|
||||||
@@ -157,6 +168,8 @@ func TestToString(t *testing.T) {
|
|||||||
"12.3", "12.3",
|
"12.3", "12.3",
|
||||||
"true", "false",
|
"true", "false",
|
||||||
"[1,2,3]", "{\"a\":1,\"b\":2,\"c\":3}", "{\"Name\":\"TestStruct\"}", "hello",
|
"[1,2,3]", "{\"a\":1,\"b\":2,\"c\":3}", "{\"Name\":\"TestStruct\"}", "hello",
|
||||||
|
"123", "123", "12.3", "abc", "{\"Name\":\"TestStruct\"}", "", "",
|
||||||
|
"0",
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(cases); i++ {
|
for i := 0; i < len(cases); i++ {
|
||||||
|
|||||||
@@ -1,51 +1,51 @@
|
|||||||
-----BEGIN rsa private key-----
|
-----BEGIN rsa private key-----
|
||||||
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
|
||||||
-----END rsa private key-----
|
-----END rsa private key-----
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
-----BEGIN rsa public key-----
|
-----BEGIN rsa public key-----
|
||||||
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuYcMNNn4v0OaL/Ufwj0p
|
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0HaqqGWnNqwRVKoJUUjY
|
||||||
kChajjUm1Nb3OeU4bXX26i+khkXNy6KaoRzlAfsH1Fli4iv7x6c9cde4Q63R7Wod
|
iH/dwkSK61La4RGYkvDfcuo9pDgczHVhFUb/MYWeb3bAlFAGcZLYSBh6WAGxbeMj
|
||||||
vzcH1W2HKxQ3Ht6hkeS2RKgJEm8o/Pbzr10yaULwjVLXsTkG6ssIdQLw3zwz6XRD
|
SkaLroaXnafhKZ2oXXUy8CzyYxZwpLCDgJLG7Pf0jer3STZW93ZT8UJixbKwbqD6
|
||||||
vyU66NbE3mNDIh1yAtJUmPoeRcA4QMbMM+5P888Ht6ETsLVkMx1uFYALbGidlACB
|
b8fkpMANwCYrTlXDWBuZVaEKuQNnC4XufQis4fwRxRgfrZuLMvuQVtnyYmssmnp8
|
||||||
S7hyBtc0ibWjdAG9rSZg7E3MAhz5dRYmkGAJqSA4aHWL6FT2gXXkrP36D4+hbQA6
|
JHovYkr87giDjEgvlrC84Lez32ZhEhORRu5NGEDeZ1OewbkXGyQtbcBQYNAxgnOc
|
||||||
UsBLxs5nM4Cl7fzdysJWv1suldiB84+gYRmiumsj/odwVcxxFcxI1sDgabzI5IKT
|
O44MTTPhEdz4/A0xwzEe+yIOxWIAWuEM2rclXpZBW/MEK41gZ3C04KcX5R0KRdj2
|
||||||
waGLLz5hu+7in9lAIEqtfH/Ui5pfEw8qH1ymkLnlkSAtTZ4ByMaw869zP0AYnn1m
|
PTTH7vJ33yRC4hKtWetwMvsUrewrRKVcUgaeFykDAlgIDoSWvG0nzb70AWSoNcj7
|
||||||
p+dJ5Mo1mqy0+qZn2E4FITrAOgr306D/7Ce1ZE+UZ2/i7hpkcdAD1PdY1c+Ffmps
|
krLlwEc2WLGy/kCYWppnfYKafEJXpgblHrDFKlWvte68yrvGdCsWRLQ2uUF0xokQ
|
||||||
osZ/WVcvHUH65Fz1TR6YMz0poeBj27+CBziA6P1MKfBNpBx+UfHomK5O2356S90z
|
Ig4u2bApyWNroxEtjHwUp1VeJuZBQkfg+vIW+t3moQpMtlhy4aai/oGIxI5TIB82
|
||||||
qd5z0W6t1rkgLSPcR592yszAM72h+KHUtGB/rs6OUum4yfw3EVA4R4plO1lU50sc
|
nv8TPVczjHmmE3hwL6nZ5OfbFyWpRFvKLtXcaAKMi2HqOLRkQhqjjJUCO9Wyhu1B
|
||||||
UgwducOB7ihYSQPU87IPHcydWQ5NLobygxzqNYpIb0pPrLTBP1ZM9v6wY16xs6kC
|
kX8RAeKLl3S7gRyhuOB5JNUGEpQ389MdbUX5S12Qp1xTDS+otbC8tYS1gu0OOOWo
|
||||||
knmr3e7aQckxq17MuNIkewsCAwEAAQ==
|
wxbuF5+Ci2SYgSHv/3zXKoMCAwEAAQ==
|
||||||
-----END rsa public key-----
|
-----END rsa public key-----
|
||||||
|
|||||||
@@ -64,28 +64,95 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddMinute add or sub minute to the time.
|
// AddMinute add or sub minutes to the time.
|
||||||
// Play: https://go.dev/play/p/nT1heB1KUUK
|
// Play: https://go.dev/play/p/nT1heB1KUUK
|
||||||
func AddMinute(t time.Time, minute int64) time.Time {
|
func AddMinute(t time.Time, minutes int64) time.Time {
|
||||||
return t.Add(time.Minute * time.Duration(minute))
|
return t.Add(time.Minute * time.Duration(minutes))
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddHour add or sub hour to the time.
|
// AddHour add or sub hours to the time.
|
||||||
// Play: https://go.dev/play/p/rcMjd7OCsi5
|
// Play: https://go.dev/play/p/rcMjd7OCsi5
|
||||||
func AddHour(t time.Time, hour int64) time.Time {
|
func AddHour(t time.Time, hours int64) time.Time {
|
||||||
return t.Add(time.Hour * time.Duration(hour))
|
return t.Add(time.Hour * time.Duration(hours))
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddDay add or sub day to the time.
|
// AddDay add or sub days to the time.
|
||||||
// Play: https://go.dev/play/p/dIGbs_uTdFa
|
// Play: https://go.dev/play/p/dIGbs_uTdFa
|
||||||
func AddDay(t time.Time, day int64) time.Time {
|
func AddDay(t time.Time, days int64) time.Time {
|
||||||
return t.Add(24 * time.Hour * time.Duration(day))
|
return t.Add(24 * time.Hour * time.Duration(days))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddWeek add or sub weeks to the time.
|
||||||
|
// play: todo
|
||||||
|
func AddWeek(t time.Time, weeks int64) time.Time {
|
||||||
|
return t.Add(7 * 24 * time.Hour * time.Duration(weeks))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddMonth add or sub months to the time.
|
||||||
|
// Play: todo
|
||||||
|
func AddMonth(t time.Time, months int64) time.Time {
|
||||||
|
return t.AddDate(0, int(months), 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddYear add or sub year to the time.
|
// AddYear add or sub year to the time.
|
||||||
// Play: https://go.dev/play/p/MqW2ujnBx10
|
// Play: https://go.dev/play/p/MqW2ujnBx10
|
||||||
func AddYear(t time.Time, year int64) time.Time {
|
func AddYear(t time.Time, year int64) time.Time {
|
||||||
return t.Add(365 * 24 * time.Hour * time.Duration(year))
|
return t.AddDate(int(year), 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddDaySafe add or sub days to the time and ensure that the returned date does not exceed the valid date of the target year and month.
|
||||||
|
// Play: todo
|
||||||
|
func AddDaySafe(t time.Time, days int) time.Time {
|
||||||
|
t = t.AddDate(0, 0, days)
|
||||||
|
year, month, day := t.Date()
|
||||||
|
|
||||||
|
lastDayOfMonth := time.Date(year, month+1, 0, 0, 0, 0, 0, t.Location()).Day()
|
||||||
|
|
||||||
|
if day > lastDayOfMonth {
|
||||||
|
t = time.Date(year, month, lastDayOfMonth, t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), t.Location())
|
||||||
|
}
|
||||||
|
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddMonthSafe add or sub months to the time and ensure that the returned date does not exceed the valid date of the target year and month.
|
||||||
|
// Play: todo
|
||||||
|
func AddMonthSafe(t time.Time, months int) time.Time {
|
||||||
|
year := t.Year()
|
||||||
|
month := int(t.Month()) + months
|
||||||
|
|
||||||
|
for month > 12 {
|
||||||
|
month -= 12
|
||||||
|
year++
|
||||||
|
}
|
||||||
|
for month < 1 {
|
||||||
|
month += 12
|
||||||
|
year--
|
||||||
|
}
|
||||||
|
|
||||||
|
daysInMonth := time.Date(year, time.Month(month+1), 0, 0, 0, 0, 0, time.UTC).Day()
|
||||||
|
|
||||||
|
day := t.Day()
|
||||||
|
if day > daysInMonth {
|
||||||
|
day = daysInMonth
|
||||||
|
}
|
||||||
|
|
||||||
|
return time.Date(year, time.Month(month), day, t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), t.Location())
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddYearSafe add or sub years to the time and ensure that the returned date does not exceed the valid date of the target year and month.
|
||||||
|
// Play: todo
|
||||||
|
func AddYearSafe(t time.Time, years int) time.Time {
|
||||||
|
year, month, day := t.Date()
|
||||||
|
year += years
|
||||||
|
|
||||||
|
if month == time.February && day == 29 {
|
||||||
|
if !IsLeapYear(year) {
|
||||||
|
day = 28
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return time.Date(year, month, day, t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), t.Location())
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNowDate return format yyyy-mm-dd of current date.
|
// GetNowDate return format yyyy-mm-dd of current date.
|
||||||
|
|||||||
@@ -7,71 +7,141 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func ExampleAddDay() {
|
func ExampleAddDay() {
|
||||||
now := time.Now()
|
date, _ := time.Parse("2006-01-02 15:04:05", "2021-01-01 00:00:00")
|
||||||
|
|
||||||
tomorrow := AddDay(now, 1)
|
after1Day := AddDay(date, 1)
|
||||||
diff1 := tomorrow.Sub(now)
|
before1Day := AddDay(date, -1)
|
||||||
|
|
||||||
yesterday := AddDay(now, -1)
|
fmt.Println(after1Day.Format("2006-01-02 15:04:05"))
|
||||||
diff2 := yesterday.Sub(now)
|
fmt.Println(before1Day.Format("2006-01-02 15:04:05"))
|
||||||
|
|
||||||
fmt.Println(diff1)
|
|
||||||
fmt.Println(diff2)
|
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// 24h0m0s
|
// 2021-01-02 00:00:00
|
||||||
// -24h0m0s
|
// 2020-12-31 00:00:00
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleAddWeek() {
|
||||||
|
date, _ := time.Parse("2006-01-02", "2021-01-01")
|
||||||
|
|
||||||
|
after2Weeks := AddWeek(date, 2)
|
||||||
|
before2Weeks := AddWeek(date, -2)
|
||||||
|
|
||||||
|
fmt.Println(after2Weeks.Format("2006-01-02"))
|
||||||
|
fmt.Println(before2Weeks.Format("2006-01-02"))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2021-01-15
|
||||||
|
// 2020-12-18
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleAddMonth() {
|
||||||
|
date, _ := time.Parse("2006-01-02", "2021-01-01")
|
||||||
|
|
||||||
|
after2Months := AddMonth(date, 2)
|
||||||
|
before2Months := AddMonth(date, -2)
|
||||||
|
|
||||||
|
fmt.Println(after2Months.Format("2006-01-02"))
|
||||||
|
fmt.Println(before2Months.Format("2006-01-02"))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2021-03-01
|
||||||
|
// 2020-11-01
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleAddHour() {
|
func ExampleAddHour() {
|
||||||
now := time.Now()
|
date, _ := time.Parse("2006-01-02 15:04:05", "2021-01-01 00:00:00")
|
||||||
|
|
||||||
after2Hours := AddHour(now, 2)
|
after2Hours := AddHour(date, 2)
|
||||||
diff1 := after2Hours.Sub(now)
|
before2Hours := AddHour(date, -2)
|
||||||
|
|
||||||
before2Hours := AddHour(now, -2)
|
fmt.Println(after2Hours.Format("2006-01-02 15:04:05"))
|
||||||
diff2 := before2Hours.Sub(now)
|
fmt.Println(before2Hours.Format("2006-01-02 15:04:05"))
|
||||||
|
|
||||||
fmt.Println(diff1)
|
|
||||||
fmt.Println(diff2)
|
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// 2h0m0s
|
// 2021-01-01 02:00:00
|
||||||
// -2h0m0s
|
// 2020-12-31 22:00:00
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleAddMinute() {
|
func ExampleAddMinute() {
|
||||||
now := time.Now()
|
date, _ := time.Parse("2006-01-02 15:04:05", "2021-01-01 00:00:00")
|
||||||
|
|
||||||
after2Minutes := AddMinute(now, 2)
|
after2Minutes := AddMinute(date, 2)
|
||||||
diff1 := after2Minutes.Sub(now)
|
before2Minutes := AddMinute(date, -2)
|
||||||
|
|
||||||
before2Minutes := AddMinute(now, -2)
|
fmt.Println(after2Minutes.Format("2006-01-02 15:04:05"))
|
||||||
diff2 := before2Minutes.Sub(now)
|
fmt.Println(before2Minutes.Format("2006-01-02 15:04:05"))
|
||||||
|
|
||||||
fmt.Println(diff1)
|
|
||||||
fmt.Println(diff2)
|
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// 2m0s
|
// 2021-01-01 00:02:00
|
||||||
// -2m0s
|
// 2020-12-31 23:58:00
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleAddYear() {
|
func ExampleAddYear() {
|
||||||
now := time.Now()
|
date, _ := time.Parse("2006-01-02", "2021-01-01")
|
||||||
|
|
||||||
after1Year := AddYear(now, 1)
|
after2Years := AddYear(date, 2)
|
||||||
diff1 := after1Year.Sub(now)
|
before2Years := AddYear(date, -2)
|
||||||
|
|
||||||
before1Year := AddYear(now, -1)
|
fmt.Println(after2Years.Format("2006-01-02"))
|
||||||
diff2 := before1Year.Sub(now)
|
fmt.Println(before2Years.Format("2006-01-02"))
|
||||||
|
|
||||||
fmt.Println(diff1)
|
|
||||||
fmt.Println(diff2)
|
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// 8760h0m0s
|
// 2023-01-01
|
||||||
// -8760h0m0s
|
// 2019-01-01
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleAddDaySafe() {
|
||||||
|
leapYearDate1, _ := time.Parse("2006-01-02", "2024-02-29")
|
||||||
|
result1 := AddDaySafe(leapYearDate1, 1)
|
||||||
|
|
||||||
|
leapYearDate2, _ := time.Parse("2006-01-02", "2024-03-01")
|
||||||
|
result2 := AddDaySafe(leapYearDate2, -1)
|
||||||
|
|
||||||
|
nonLeapYearDate1, _ := time.Parse("2006-01-02", "2025-02-28")
|
||||||
|
result3 := AddDaySafe(nonLeapYearDate1, 1)
|
||||||
|
|
||||||
|
nonLeaYearDate2, _ := time.Parse("2006-01-02", "2025-03-01")
|
||||||
|
result4 := AddDaySafe(nonLeaYearDate2, -1)
|
||||||
|
|
||||||
|
fmt.Println(result1.Format("2006-01-02"))
|
||||||
|
fmt.Println(result2.Format("2006-01-02"))
|
||||||
|
fmt.Println(result3.Format("2006-01-02"))
|
||||||
|
fmt.Println(result4.Format("2006-01-02"))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2024-03-01
|
||||||
|
// 2024-02-29
|
||||||
|
// 2025-03-01
|
||||||
|
// 2025-02-28
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleAddMonthSafe() {
|
||||||
|
date1, _ := time.Parse("2006-01-02", "2025-01-31")
|
||||||
|
result1 := AddMonthSafe(date1, 1)
|
||||||
|
|
||||||
|
date2, _ := time.Parse("2006-01-02", "2024-02-29")
|
||||||
|
result2 := AddMonthSafe(date2, -1)
|
||||||
|
|
||||||
|
fmt.Println(result1.Format("2006-01-02"))
|
||||||
|
fmt.Println(result2.Format("2006-01-02"))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2025-02-28
|
||||||
|
// 2024-01-29
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleAddYearSafe() {
|
||||||
|
date, _ := time.Parse("2006-01-02", "2020-02-29")
|
||||||
|
|
||||||
|
result1 := AddYearSafe(date, 1)
|
||||||
|
result2 := AddYearSafe(date, -1)
|
||||||
|
|
||||||
|
fmt.Println(result1.Format("2006-01-02"))
|
||||||
|
fmt.Println(result2.Format("2006-01-02"))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2021-02-28
|
||||||
|
// 2019-02-28
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleGetNowDate() {
|
func ExampleGetNowDate() {
|
||||||
|
|||||||
@@ -9,78 +9,427 @@ import (
|
|||||||
|
|
||||||
func TestAddYear(t *testing.T) {
|
func TestAddYear(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
assert := internal.NewAssert(t, "TestAddDay")
|
assert := internal.NewAssert(t, "TestAddDay")
|
||||||
|
|
||||||
now := time.Now()
|
tests := []struct {
|
||||||
after2Years := AddYear(now, 1)
|
inputDate string
|
||||||
diff1 := after2Years.Sub(now)
|
years int
|
||||||
assert.Equal(float64(8760), diff1.Hours())
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
years: 1,
|
||||||
|
expected: "2022-01-01 00:00:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
years: -1,
|
||||||
|
expected: "2020-01-01 00:00:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
years: 0,
|
||||||
|
expected: "2021-01-01 00:00:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
years: 2,
|
||||||
|
expected: "2023-01-01 00:00:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
years: 3,
|
||||||
|
expected: "2024-01-01 00:00:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
years: 4,
|
||||||
|
expected: "2025-01-01 00:00:00",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
before2Years := AddYear(now, -1)
|
for _, tt := range tests {
|
||||||
diff2 := before2Years.Sub(now)
|
date, _ := time.Parse("2006-01-02 15:04:05", tt.inputDate)
|
||||||
assert.Equal(float64(-8760), diff2.Hours())
|
result := AddYear(date, int64(tt.years))
|
||||||
}
|
assert.Equal(tt.expected, result.Format("2006-01-02 15:04:05"))
|
||||||
|
}
|
||||||
func TestBetweenSeconds(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
assert := internal.NewAssert(t, "TestBetweenSeconds")
|
|
||||||
|
|
||||||
today := time.Now()
|
|
||||||
tomorrow := AddDay(today, 1)
|
|
||||||
yesterday := AddDay(today, -1)
|
|
||||||
|
|
||||||
result1 := BetweenSeconds(today, tomorrow)
|
|
||||||
result2 := BetweenSeconds(today, yesterday)
|
|
||||||
|
|
||||||
assert.Equal(int64(86400), result1)
|
|
||||||
assert.Equal(int64(-86400), result2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddDay(t *testing.T) {
|
func TestAddDay(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
assert := internal.NewAssert(t, "TestAddDay")
|
assert := internal.NewAssert(t, "TestAddDay")
|
||||||
|
|
||||||
now := time.Now()
|
tests := []struct {
|
||||||
after2Days := AddDay(now, 2)
|
inputDate string
|
||||||
diff1 := after2Days.Sub(now)
|
days int
|
||||||
assert.Equal(float64(48), diff1.Hours())
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
days: 1,
|
||||||
|
expected: "2021-01-02 00:00:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
days: -1,
|
||||||
|
expected: "2020-12-31 00:00:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
days: 0,
|
||||||
|
expected: "2021-01-01 00:00:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
days: 2,
|
||||||
|
expected: "2021-01-03 00:00:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
days: 3,
|
||||||
|
expected: "2021-01-04 00:00:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
days: 4,
|
||||||
|
expected: "2021-01-05 00:00:00",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
before2Days := AddDay(now, -2)
|
for _, tt := range tests {
|
||||||
diff2 := before2Days.Sub(now)
|
date, _ := time.Parse("2006-01-02 15:04:05", tt.inputDate)
|
||||||
assert.Equal(float64(-48), diff2.Hours())
|
result := AddDay(date, int64(tt.days))
|
||||||
|
assert.Equal(tt.expected, result.Format("2006-01-02 15:04:05"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddHour(t *testing.T) {
|
func TestAddHour(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
assert := internal.NewAssert(t, "TestAddHour")
|
assert := internal.NewAssert(t, "TestAddHour")
|
||||||
|
|
||||||
now := time.Now()
|
tests := []struct {
|
||||||
after2Hours := AddHour(now, 2)
|
inputDate string
|
||||||
diff1 := after2Hours.Sub(now)
|
hours int
|
||||||
assert.Equal(float64(2), diff1.Hours())
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
hours: 1,
|
||||||
|
expected: "2021-01-01 01:00:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
hours: -1,
|
||||||
|
expected: "2020-12-31 23:00:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
hours: 0,
|
||||||
|
expected: "2021-01-01 00:00:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
hours: 24,
|
||||||
|
expected: "2021-01-02 00:00:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
hours: 25,
|
||||||
|
expected: "2021-01-02 01:00:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
hours: 48,
|
||||||
|
expected: "2021-01-03 00:00:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
hours: 49,
|
||||||
|
expected: "2021-01-03 01:00:00",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
date, _ := time.Parse("2006-01-02 15:04:05", tt.inputDate)
|
||||||
|
result := AddHour(date, int64(tt.hours))
|
||||||
|
assert.Equal(tt.expected, result.Format("2006-01-02 15:04:05"))
|
||||||
|
}
|
||||||
|
|
||||||
before2Hours := AddHour(now, -2)
|
|
||||||
diff2 := before2Hours.Sub(now)
|
|
||||||
assert.Equal(float64(-2), diff2.Hours())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddMinute(t *testing.T) {
|
func TestAddMinute(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
assert := internal.NewAssert(t, "TestAddMinute")
|
assert := internal.NewAssert(t, "TestAddMinute")
|
||||||
|
|
||||||
now := time.Now()
|
tests := []struct {
|
||||||
after2Minutes := AddMinute(now, 2)
|
inputDate string
|
||||||
diff1 := after2Minutes.Sub(now)
|
minutes int
|
||||||
assert.Equal(float64(2), diff1.Minutes())
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
minutes: 1,
|
||||||
|
expected: "2021-01-01 00:01:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
minutes: -1,
|
||||||
|
expected: "2020-12-31 23:59:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
minutes: 0,
|
||||||
|
expected: "2021-01-01 00:00:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
minutes: 60,
|
||||||
|
expected: "2021-01-01 01:00:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
minutes: 61,
|
||||||
|
expected: "2021-01-01 01:01:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
minutes: 1440,
|
||||||
|
expected: "2021-01-02 00:00:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01 00:00:00",
|
||||||
|
minutes: 1441,
|
||||||
|
expected: "2021-01-02 00:01:00",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
before2Minutes := AddMinute(now, -2)
|
for _, tt := range tests {
|
||||||
diff2 := before2Minutes.Sub(now)
|
date, _ := time.Parse("2006-01-02 15:04:05", tt.inputDate)
|
||||||
assert.Equal(float64(-2), diff2.Minutes())
|
result := AddMinute(date, int64(tt.minutes))
|
||||||
|
assert.Equal(tt.expected, result.Format("2006-01-02 15:04:05"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddWeek(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
assert := internal.NewAssert(t, "TestAddWeek")
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
inputDate string
|
||||||
|
weeks int
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01",
|
||||||
|
weeks: 1,
|
||||||
|
expected: "2021-01-08",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01",
|
||||||
|
weeks: -1,
|
||||||
|
expected: "2020-12-25",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01",
|
||||||
|
weeks: 0,
|
||||||
|
expected: "2021-01-01",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01",
|
||||||
|
weeks: 52,
|
||||||
|
expected: "2021-12-31",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01",
|
||||||
|
weeks: 53,
|
||||||
|
expected: "2022-01-07",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01",
|
||||||
|
weeks: 104,
|
||||||
|
expected: "2022-12-30",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
date, _ := time.Parse("2006-01-02", tt.inputDate)
|
||||||
|
result := AddWeek(date, int64(tt.weeks))
|
||||||
|
assert.Equal(tt.expected, result.Format("2006-01-02"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddMonth(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
assert := internal.NewAssert(t, "TestAddMonth")
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
inputDate string
|
||||||
|
months int
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01",
|
||||||
|
months: 1,
|
||||||
|
expected: "2021-02-01",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01",
|
||||||
|
months: -1,
|
||||||
|
expected: "2020-12-01",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01",
|
||||||
|
months: 0,
|
||||||
|
expected: "2021-01-01",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01",
|
||||||
|
months: 12,
|
||||||
|
expected: "2022-01-01",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01",
|
||||||
|
months: 13,
|
||||||
|
expected: "2022-02-01",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2021-01-01",
|
||||||
|
months: 24,
|
||||||
|
expected: "2023-01-01",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
date, _ := time.Parse("2006-01-02", tt.inputDate)
|
||||||
|
result := AddMonth(date, int64(tt.months))
|
||||||
|
assert.Equal(tt.expected, result.Format("2006-01-02"))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddDaySafe(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
assert := internal.NewAssert(t, "TestAddDaySafe")
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
inputDate string
|
||||||
|
days int
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{"2025-01-31", 10, "2025-02-10"},
|
||||||
|
{"2025-01-01", 30, "2025-01-31"},
|
||||||
|
{"2025-01-31", 1, "2025-02-01"},
|
||||||
|
{"2025-02-28", 1, "2025-03-01"},
|
||||||
|
{"2024-02-29", 1, "2024-03-01"},
|
||||||
|
{"2024-02-29", 365, "2025-02-28"},
|
||||||
|
|
||||||
|
{"2025-01-31", -10, "2025-01-21"},
|
||||||
|
{"2025-01-01", -30, "2024-12-02"},
|
||||||
|
{"2025-02-01", -1, "2025-01-31"},
|
||||||
|
{"2025-03-01", -1, "2025-02-28"},
|
||||||
|
{"2024-03-01", -1, "2024-02-29"},
|
||||||
|
|
||||||
|
{"2025-01-31", -31, "2024-12-31"},
|
||||||
|
{"2025-12-31", 1, "2026-01-01"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
date, _ := time.Parse("2006-01-02", tt.inputDate)
|
||||||
|
result := AddDaySafe(date, tt.days)
|
||||||
|
assert.Equal(tt.expected, result.Format("2006-01-02"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddMonthSafe(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
assert := internal.NewAssert(t, "TestAddMonthSafe")
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
inputDate string
|
||||||
|
months int
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
inputDate: "2025-01-31",
|
||||||
|
months: 1,
|
||||||
|
expected: "2025-02-28",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2025-01-31",
|
||||||
|
months: -1,
|
||||||
|
expected: "2024-12-31",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2025-12-31",
|
||||||
|
months: 1,
|
||||||
|
expected: "2026-01-31",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2025-01-31",
|
||||||
|
months: -1,
|
||||||
|
expected: "2024-12-31",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2024-02-29",
|
||||||
|
months: 1,
|
||||||
|
expected: "2024-03-29",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2024-02-29",
|
||||||
|
months: -1,
|
||||||
|
expected: "2024-01-29",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
date, _ := time.Parse("2006-01-02", tt.inputDate)
|
||||||
|
result := AddMonthSafe(date, tt.months)
|
||||||
|
assert.Equal(tt.expected, result.Format("2006-01-02"))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddYearSafe(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
assert := internal.NewAssert(t, "TestAddYearSafe")
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
inputDate string
|
||||||
|
years int
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
inputDate: "2020-02-29",
|
||||||
|
years: 1,
|
||||||
|
expected: "2021-02-28",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2020-02-29",
|
||||||
|
years: 2,
|
||||||
|
expected: "2022-02-28",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2020-02-29",
|
||||||
|
years: -1,
|
||||||
|
expected: "2019-02-28",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputDate: "2020-02-29",
|
||||||
|
years: -2,
|
||||||
|
expected: "2018-02-28",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
date, _ := time.Parse("2006-01-02", tt.inputDate)
|
||||||
|
result := AddYearSafe(date, tt.years)
|
||||||
|
assert.Equal(tt.expected, result.Format("2006-01-02"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetNowDate(t *testing.T) {
|
func TestGetNowDate(t *testing.T) {
|
||||||
@@ -578,3 +927,19 @@ func TestMaxMin(t *testing.T) {
|
|||||||
assert.Equal(oneMinuteAgo, min)
|
assert.Equal(oneMinuteAgo, min)
|
||||||
assert.Equal(oneMinuteAfter, max)
|
assert.Equal(oneMinuteAfter, max)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBetweenSeconds(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
assert := internal.NewAssert(t, "TestBetweenSeconds")
|
||||||
|
|
||||||
|
today := time.Now()
|
||||||
|
tomorrow := AddDay(today, 1)
|
||||||
|
yesterday := AddDay(today, -1)
|
||||||
|
|
||||||
|
result1 := BetweenSeconds(today, tomorrow)
|
||||||
|
result2 := BetweenSeconds(today, yesterday)
|
||||||
|
|
||||||
|
assert.Equal(int64(86400), result1)
|
||||||
|
assert.Equal(int64(-86400), result2)
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,9 +23,14 @@ import (
|
|||||||
## 目录
|
## 目录
|
||||||
|
|
||||||
- [AddDay](#AddDay)
|
- [AddDay](#AddDay)
|
||||||
|
- [AddWeek](#AddWeek)
|
||||||
|
- [AddMonth](#AddMonth)
|
||||||
- [AddHour](#AddHour)
|
- [AddHour](#AddHour)
|
||||||
- [AddMinute](#AddMinute)
|
- [AddMinute](#AddMinute)
|
||||||
- [AddYear](#AddYear)
|
- [AddYear](#AddYear)
|
||||||
|
- [AddDaySafe](#AddDaySafe)
|
||||||
|
- [AddMonthSafe](#AddMonthSafe)
|
||||||
|
- [AddYearSafe](#AddYearSafe)
|
||||||
- [BeginOfMinute](#BeginOfMinute)
|
- [BeginOfMinute](#BeginOfMinute)
|
||||||
- [BeginOfHour](#BeginOfHour)
|
- [BeginOfHour](#BeginOfHour)
|
||||||
- [BeginOfDay](#BeginOfDay)
|
- [BeginOfDay](#BeginOfDay)
|
||||||
@@ -109,7 +114,7 @@ import (
|
|||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func AddDay(t time.Time, day int64) time.Time
|
func AddDay(t time.Time, days int64) time.Time
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/dIGbs_uTdFa)</span></b>
|
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/dIGbs_uTdFa)</span></b>
|
||||||
@@ -124,20 +129,89 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
now := time.Now()
|
date, _ := time.Parse("2006-01-02 15:04:05", "2021-01-01 00:00:00")
|
||||||
|
|
||||||
tomorrow := datetime.AddDay(now, 1)
|
after1Day := datetime.AddDay(date, 1)
|
||||||
diff1 := tomorrow.Sub(now)
|
before1Day := datetime.AddDay(date, -1)
|
||||||
|
|
||||||
yesterday := datetime.AddDay(now, -1)
|
fmt.Println(after1Day.Format("2006-01-02 15:04:05"))
|
||||||
diff2 := yesterday.Sub(now)
|
fmt.Println(before1Day.Format("2006-01-02 15:04:05"))
|
||||||
|
|
||||||
fmt.Println(diff1)
|
|
||||||
fmt.Println(diff2)
|
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// 24h0m0s
|
// 2021-01-02 00:00:00
|
||||||
// -24h0m0s
|
// 2020-12-31 00:00:00
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="AddWeek">AddWeek</span>
|
||||||
|
|
||||||
|
<p>将日期加/减星期数。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func AddWeek(t time.Time, weeks int64) time.Time
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
date, _ := time.Parse("2006-01-02", "2021-01-01")
|
||||||
|
|
||||||
|
after2Weeks := datetime.AddWeek(date, 2)
|
||||||
|
before2Weeks := datetime.AddWeek(date, -2)
|
||||||
|
|
||||||
|
fmt.Println(after2Weeks.Format("2006-01-02"))
|
||||||
|
fmt.Println(before2Weeks.Format("2006-01-02"))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2021-01-15
|
||||||
|
// 2020-12-18
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="AddMonth">AddMonth</span>
|
||||||
|
|
||||||
|
<p>将日期加/减月数。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func AddMonth(t time.Time, months int64) time.Time
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
date, _ := time.Parse("2006-01-02", "2021-01-01")
|
||||||
|
|
||||||
|
after2Months := datetime.AddMonth(date, 2)
|
||||||
|
before2Months := datetime.AddMonth(date, -2)
|
||||||
|
|
||||||
|
fmt.Println(after2Months.Format("2006-01-02"))
|
||||||
|
fmt.Println(before2Months.Format("2006-01-02"))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2021-03-01
|
||||||
|
// 2020-11-01
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -148,7 +222,7 @@ func main() {
|
|||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func AddHour(t time.Time, hour int64) time.Time
|
func AddHour(t time.Time, hours int64) time.Time
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/rcMjd7OCsi5)</span></b>
|
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/rcMjd7OCsi5)</span></b>
|
||||||
@@ -163,20 +237,17 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
now := time.Now()
|
date, _ := time.Parse("2006-01-02 15:04:05", "2021-01-01 00:00:00")
|
||||||
|
|
||||||
after2Hours := datetime.AddHour(now, 2)
|
after2Hours := datetime.AddHour(date, 2)
|
||||||
diff1 := after2Hours.Sub(now)
|
before2Hours := datetime.AddHour(date, -2)
|
||||||
|
|
||||||
before2Hours := datetime.AddHour(now, -2)
|
fmt.Println(after2Hours.Format("2006-01-02 15:04:05"))
|
||||||
diff2 := before2Hours.Sub(now)
|
fmt.Println(before2Hours.Format("2006-01-02 15:04:05"))
|
||||||
|
|
||||||
fmt.Println(diff1)
|
|
||||||
fmt.Println(diff2)
|
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// 2h0m0s
|
// 2021-01-01 02:00:00
|
||||||
// -2h0m0s
|
// 2020-12-31 22:00:00
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -187,7 +258,7 @@ func main() {
|
|||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func AddMinute(t time.Time, minute int64) time.Time
|
func AddMinute(t time.Time, minutes int64) time.Time
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/nT1heB1KUUK)</span></b>
|
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/nT1heB1KUUK)</span></b>
|
||||||
@@ -202,20 +273,17 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
now := time.Now()
|
date, _ := time.Parse("2006-01-02 15:04:05", "2021-01-01 00:00:00")
|
||||||
|
|
||||||
after2Minutes := datetime.AddMinute(now, 2)
|
after2Minutes := datetime.AddMinute(date, 2)
|
||||||
diff1 := after2Minutes.Sub(now)
|
before2Minutes := datetime.AddMinute(date, -2)
|
||||||
|
|
||||||
before2Minutes := datetime.AddMinute(now, -2)
|
fmt.Println(after2Minutes.Format("2006-01-02 15:04:05"))
|
||||||
diff2 := before2Minutes.Sub(now)
|
fmt.Println(before2Minutes.Format("2006-01-02 15:04:05"))
|
||||||
|
|
||||||
fmt.Println(diff1)
|
|
||||||
fmt.Println(diff2)
|
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// 2m0s
|
// 2021-01-01 00:02:00
|
||||||
// -2m0s
|
// 2020-12-31 23:58:00
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -226,7 +294,7 @@ func main() {
|
|||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func AddYear(t time.Time, year int64) time.Time
|
func AddYear(t time.Time, years int64) time.Time
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/MqW2ujnBx10)</span></b>
|
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/MqW2ujnBx10)</span></b>
|
||||||
@@ -241,20 +309,137 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
now := time.Now()
|
date, _ := time.Parse("2006-01-02", "2021-01-01")
|
||||||
|
|
||||||
after1Year := datetime.AddYear(now, 1)
|
after2Years := AddYear(date, 2)
|
||||||
diff1 := after1Year.Sub(now)
|
before2Years := AddYear(date, -2)
|
||||||
|
|
||||||
before1Year := datetime.AddYear(now, -1)
|
fmt.Println(after2Years.Format("2006-01-02"))
|
||||||
diff2 := before1Year.Sub(now)
|
fmt.Println(before2Years.Format("2006-01-02"))
|
||||||
|
|
||||||
fmt.Println(diff1)
|
|
||||||
fmt.Println(diff2)
|
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// 8760h0m0s
|
// 2023-01-01
|
||||||
// -8760h0m0s
|
// 2019-01-01
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="AddDaySafe">AddDaySafe</span>
|
||||||
|
|
||||||
|
<p>增加/减少指定的天数,并确保日期是有效日期。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func AddDaySafe(t time.Time, days int) time.Time
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
leapYearDate1, _ := time.Parse("2006-01-02", "2024-02-29")
|
||||||
|
result1 := datetime.AddDaySafe(leapYearDate1, 1)
|
||||||
|
|
||||||
|
leapYearDate2, _ := time.Parse("2006-01-02", "2024-03-01")
|
||||||
|
result2 := datetime.AddDaySafe(leapYearDate2, -1)
|
||||||
|
|
||||||
|
nonLeapYearDate1, _ := time.Parse("2006-01-02", "2025-02-28")
|
||||||
|
result3 := datetime.AddDaySafe(nonLeapYearDate1, 1)
|
||||||
|
|
||||||
|
nonLeaYearDate2, _ := time.Parse("2006-01-02", "2025-03-01")
|
||||||
|
result4 := datetime.AddDaySafe(nonLeaYearDate2, -1)
|
||||||
|
|
||||||
|
fmt.Println(result1.Format("2006-01-02"))
|
||||||
|
fmt.Println(result2.Format("2006-01-02"))
|
||||||
|
fmt.Println(result3.Format("2006-01-02"))
|
||||||
|
fmt.Println(result4.Format("2006-01-02"))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2024-03-01
|
||||||
|
// 2024-02-29
|
||||||
|
// 2025-03-01
|
||||||
|
// 2025-02-28
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="AddMonthSafe">AddMonthSafe</span>
|
||||||
|
|
||||||
|
<p>增加/减少指定的月份,并确保日期是有效日期。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func AddMonthSafe(t time.Time, months int) time.Time
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
date1, _ := time.Parse("2006-01-02", "2025-01-31")
|
||||||
|
result1 := datetime.AddMonthSafe(date1, 1)
|
||||||
|
|
||||||
|
date2, _ := time.Parse("2006-01-02", "2024-02-29")
|
||||||
|
result2 := datetime.AddMonthSafe(date2, -1)
|
||||||
|
|
||||||
|
fmt.Println(result1.Format("2006-01-02"))
|
||||||
|
fmt.Println(result2.Format("2006-01-02"))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2025-02-28
|
||||||
|
// 2024-01-29
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="AddYearSafe">AddYearSafe</span>
|
||||||
|
|
||||||
|
<p>增加/减少指定的年份,并确保日期是有效日期。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func AddYearSafe(t time.Time, years int) time.Time
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
date, _ := time.Parse("2006-01-02", "2020-02-29")
|
||||||
|
|
||||||
|
result1 := datetime.AddYearSafe(date, 1)
|
||||||
|
result2 := datetime.AddYearSafe(date, -1)
|
||||||
|
|
||||||
|
fmt.Println(result1.Format("2006-01-02"))
|
||||||
|
fmt.Println(result2.Format("2006-01-02"))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2021-02-28
|
||||||
|
// 2019-02-28
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
401
docs/api/packages/eventbus.md
Normal file
401
docs/api/packages/eventbus.md
Normal file
@@ -0,0 +1,401 @@
|
|||||||
|
# EventBus
|
||||||
|
|
||||||
|
EventbBus是一个事件总线,用于在应用程序中处理事件。
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## 源码:
|
||||||
|
|
||||||
|
- [https://github.com/duke-git/lancet/blob/main/eventbus/eventbus.go](https://github.com/duke-git/lancet/blob/main/eventbus/eventbus.go)
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## 用法:
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## 目录
|
||||||
|
|
||||||
|
- [NewEventBus](#NewEventBus)
|
||||||
|
- [Subscribe](#Subscribe)
|
||||||
|
- [Unsubscribe](#Unsubscribe)
|
||||||
|
- [Publish](#Publish)
|
||||||
|
- [ClearListeners](#ClearListeners)
|
||||||
|
- [ClearListenersByTopic](#ClearListenersByTopic)
|
||||||
|
- [GetListenersCount](#GetListenersCount)
|
||||||
|
- [GetAllListenersCount](#GetAllListenersCount)
|
||||||
|
- [GetEvents](#GetEvents)
|
||||||
|
- [SetErrorHandler](#SetErrorHandler)
|
||||||
|
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## 文档
|
||||||
|
|
||||||
|
### <span id="NewEventBus">NewEventBus</span>
|
||||||
|
|
||||||
|
<p>创建EventBus实例。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewEventBus[T any]() *EventBus[T]
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
eb := eventbus.NewEventBus[int]()
|
||||||
|
|
||||||
|
receivedData := 0
|
||||||
|
listener := func(eventData int) {
|
||||||
|
receivedData = eventData
|
||||||
|
}
|
||||||
|
|
||||||
|
eb.Subscribe("event1", listener, false, 0, nil)
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
|
||||||
|
|
||||||
|
fmt.Println(receivedData)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Subscribe">Subscribe</span>
|
||||||
|
|
||||||
|
<p>订阅具有特定事件主题和监听函数的事件。支持异步,事件优先级,事件过滤器。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (eb *EventBus[T]) Subscribe(topic string, listener func(eventData T), async bool, priority int, filter func(eventData T) bool)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
eb := eventbus.NewEventBus[int]()
|
||||||
|
|
||||||
|
receivedData := 0
|
||||||
|
listener := func(eventData int) {
|
||||||
|
receivedData = eventData
|
||||||
|
}
|
||||||
|
|
||||||
|
filter := func(eventData int) bool {
|
||||||
|
return eventData == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
eb.Subscribe("event1", listener, false, 0, filter)
|
||||||
|
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 2})
|
||||||
|
|
||||||
|
fmt.Println(receivedData)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Unsubscribe">Unsubscribe</span>
|
||||||
|
|
||||||
|
<p>取消订阅具有特定事件主题的事件。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (eb *EventBus[T]) Unsubscribe(topic string, listener func(eventData T))
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
eb := eventbus.NewEventBus[int]()
|
||||||
|
|
||||||
|
receivedData := 0
|
||||||
|
listener := func(eventData int) {
|
||||||
|
receivedData = eventData
|
||||||
|
}
|
||||||
|
|
||||||
|
eb.Subscribe("event1", listener, false, 0, nil)
|
||||||
|
eb.Unsubscribe("event1", listener)
|
||||||
|
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
|
||||||
|
|
||||||
|
fmt.Println(receivedData)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Publish">Publish</span>
|
||||||
|
|
||||||
|
<p>发布一个带有特定事件主题和数据负载的事件。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (eb *EventBus[T]) Publish(event Event[T])
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
eb := eventbus.NewEventBus[int]()
|
||||||
|
|
||||||
|
eb.Subscribe("event1", func(eventData int) {
|
||||||
|
fmt.Println(eventData)
|
||||||
|
}, false, 0, nil)
|
||||||
|
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="ClearListeners">ClearListeners</span>
|
||||||
|
|
||||||
|
<p>清空所有事件监听器。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (eb *EventBus[T]) ClearListeners()
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
eb := eventbus.NewEventBus[int]()
|
||||||
|
|
||||||
|
receivedData := 0
|
||||||
|
listener := func(eventData int) {
|
||||||
|
receivedData = eventData
|
||||||
|
}
|
||||||
|
|
||||||
|
eb.Subscribe("event1", listener, false, 0, nil)
|
||||||
|
eb.ClearListeners()
|
||||||
|
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
|
||||||
|
|
||||||
|
fmt.Println(receivedData)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="ClearListenersByTopic">ClearListenersByTopic</span>
|
||||||
|
|
||||||
|
<p>清空特定事件监听器。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (eb *EventBus[T]) ClearListenersByTopic(topic string)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
eb := eventbus.NewEventBus[int]()
|
||||||
|
|
||||||
|
receivedData := 0
|
||||||
|
listener := func(eventData int) {
|
||||||
|
receivedData = eventData
|
||||||
|
}
|
||||||
|
|
||||||
|
eb.Subscribe("event1", listener, false, 0, nil)
|
||||||
|
eb.ClearListenersByTopic("event1")
|
||||||
|
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
|
||||||
|
|
||||||
|
fmt.Println(receivedData)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="GetListenersCount">GetListenersCount</span>
|
||||||
|
|
||||||
|
<p>获取特定事件的监听器数量。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (eb *EventBus[T]) GetListenersCount(topic string) int
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
eb := eventbus.NewEventBus[int]()
|
||||||
|
|
||||||
|
eb.Subscribe("event1", func(eventData int) {}, false, 0, nil)
|
||||||
|
eb.Subscribe("event1", func(eventData int) {}, false, 0, nil)
|
||||||
|
|
||||||
|
count := eb.GetListenersCount("event1")
|
||||||
|
|
||||||
|
fmt.Println(count)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="GetAllListenersCount">GetAllListenersCount</span>
|
||||||
|
|
||||||
|
<p>获取所有事件的监听器数量。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (eb *EventBus[T]) GetAllListenersCount() int
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
eb := eventbus.NewEventBus[int]()
|
||||||
|
|
||||||
|
eb.Subscribe("event1", func(eventData int) {}, false, 0, nil)
|
||||||
|
eb.Subscribe("event2", func(eventData int) {}, false, 0, nil)
|
||||||
|
|
||||||
|
count := eb.GetAllListenersCount()
|
||||||
|
|
||||||
|
fmt.Println(count)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="GetEvents">GetEvents</span>
|
||||||
|
|
||||||
|
<p>获取所有事件的topic。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (eb *EventBus[T]) GetEvents() []string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
eb := eventbus.NewEventBus[int]()
|
||||||
|
|
||||||
|
eb.Subscribe("event1", func(eventData int) {}, false, 0, nil)
|
||||||
|
eb.Subscribe("event2", func(eventData int) {}, false, 0, nil)
|
||||||
|
|
||||||
|
events := eb.GetEvents()
|
||||||
|
|
||||||
|
for _, event := range events {
|
||||||
|
fmt.Println(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// event1
|
||||||
|
// event2
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="SetErrorHandler">SetErrorHandler</span>
|
||||||
|
|
||||||
|
<p>设置事件的错误处理函数。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (eb *EventBus[T]) SetErrorHandler(handler func(err error))
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
eb := eventbus.NewEventBus[int]()
|
||||||
|
|
||||||
|
eb.SetErrorHandler(func(err error) {
|
||||||
|
fmt.Println(err)
|
||||||
|
})
|
||||||
|
|
||||||
|
eb.Subscribe("event1", func(eventData int) {
|
||||||
|
panic("error")
|
||||||
|
}, false, 0, nil)
|
||||||
|
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// error
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -70,6 +70,7 @@ import (
|
|||||||
- [FlatMap](#FlatMap)
|
- [FlatMap](#FlatMap)
|
||||||
- [Merge](#Merge)
|
- [Merge](#Merge)
|
||||||
- [Reverse](#Reverse)
|
- [Reverse](#Reverse)
|
||||||
|
- [ReverseCopy](#ReverseCopy)
|
||||||
- [Reduce<sup>deprecated</sup>](#Reduce)
|
- [Reduce<sup>deprecated</sup>](#Reduce)
|
||||||
- [ReduceConcurrent](#ReduceConcurrent)
|
- [ReduceConcurrent](#ReduceConcurrent)
|
||||||
- [ReduceBy](#ReduceBy)
|
- [ReduceBy](#ReduceBy)
|
||||||
@@ -78,6 +79,7 @@ import (
|
|||||||
- [ReplaceAll](#ReplaceAll)
|
- [ReplaceAll](#ReplaceAll)
|
||||||
- [Repeat](#Repeat)
|
- [Repeat](#Repeat)
|
||||||
- [Shuffle](#Shuffle)
|
- [Shuffle](#Shuffle)
|
||||||
|
- [ShuffleCopy](#ShuffleCopy)
|
||||||
- [IsAscending](#IsAscending)
|
- [IsAscending](#IsAscending)
|
||||||
- [IsDescending](#IsDescending)
|
- [IsDescending](#IsDescending)
|
||||||
- [IsSorted](#IsSorted)
|
- [IsSorted](#IsSorted)
|
||||||
@@ -1760,6 +1762,38 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="ReverseCopy">ReverseCopy</span>
|
||||||
|
|
||||||
|
<p>反转切片中的元素顺序, 不改变原slice。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReverseCopy[T any](slice []T) []T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
strs := []string{"a", "b", "c", "d"}
|
||||||
|
|
||||||
|
reversedStrs := slice.ReverseCopy(strs)
|
||||||
|
|
||||||
|
fmt.Println(reversedStrs)
|
||||||
|
fmt.Println(strs)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [d c b a]
|
||||||
|
// [a b c d]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="Reduce">Reduce</span>
|
### <span id="Reduce">Reduce</span>
|
||||||
|
|
||||||
<p>将切片中的元素依次运行iteratee函数,返回运行结果。</p>
|
<p>将切片中的元素依次运行iteratee函数,返回运行结果。</p>
|
||||||
@@ -1994,7 +2028,7 @@ func main() {
|
|||||||
|
|
||||||
### <span id="Shuffle">Shuffle</span>
|
### <span id="Shuffle">Shuffle</span>
|
||||||
|
|
||||||
<p>随机打乱切片中的元素顺序</p>
|
<p>随机打乱切片中的元素顺序。</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
@@ -2021,6 +2055,37 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="ShuffleCopy">ShuffleCopy</span>
|
||||||
|
|
||||||
|
<p>随机打乱切片中的元素顺序, 不改变原切片。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ShuffleCopy[T any](slice []T) []T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
nums := []int{1, 2, 3, 4, 5}
|
||||||
|
result := slice.ShuffleCopy(nums)
|
||||||
|
|
||||||
|
fmt.Println(result)
|
||||||
|
fmt.Println(nums)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [3 1 5 4 2] (random order)
|
||||||
|
// [1 2 3 4 5]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="IsAscending">IsAscending</span>
|
### <span id="IsAscending">IsAscending</span>
|
||||||
|
|
||||||
<p>检查切片元素是否按升序排列。</p>
|
<p>检查切片元素是否按升序排列。</p>
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ import (
|
|||||||
- [IsIp](#IsIp)
|
- [IsIp](#IsIp)
|
||||||
- [IsIpV4](#IsIpV4)
|
- [IsIpV4](#IsIpV4)
|
||||||
- [IsIpV6](#IsIpV6)
|
- [IsIpV6](#IsIpV6)
|
||||||
|
- [IsIpPort](#IsIpPort)
|
||||||
- [IsStrongPassword](#IsStrongPassword)
|
- [IsStrongPassword](#IsStrongPassword)
|
||||||
- [IsUrl](#IsUrl)
|
- [IsUrl](#IsUrl)
|
||||||
- [IsWeakPassword](#IsWeakPassword)
|
- [IsWeakPassword](#IsWeakPassword)
|
||||||
@@ -990,6 +991,43 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="IsIpPort">IsIpPort</span>
|
||||||
|
|
||||||
|
<p>检查字符串是否是ip:port格式。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func IsIpPort(str string) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block">[运行](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/validator"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := validator.IsIpPort("127.0.0.1:8080")
|
||||||
|
result2 := validator.IsIpPort("[0:0:0:0:0:0:0:1]:8080")
|
||||||
|
result3 := validator.IsIpPort(":8080")
|
||||||
|
result4 := validator.IsIpPort("::0:0:0:0:")
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="IsStrongPassword">IsStrongPassword</span>
|
### <span id="IsStrongPassword">IsStrongPassword</span>
|
||||||
|
|
||||||
<p>验证字符串是否是强密码:(alpha(lower+upper) + number + special chars(!@#$%^&*()?><))。</p>
|
<p>验证字符串是否是强密码:(alpha(lower+upper) + number + special chars(!@#$%^&*()?><))。</p>
|
||||||
|
|||||||
@@ -24,9 +24,14 @@ import (
|
|||||||
## Index
|
## Index
|
||||||
|
|
||||||
- [AddDay](#AddDay)
|
- [AddDay](#AddDay)
|
||||||
|
- [AddWeek](#AddWeek)
|
||||||
|
- [AddMonth](#AddMonth)
|
||||||
- [AddHour](#AddHour)
|
- [AddHour](#AddHour)
|
||||||
- [AddMinute](#AddMinute)
|
- [AddMinute](#AddMinute)
|
||||||
- [AddYear](#AddYear)
|
- [AddYear](#AddYear)
|
||||||
|
- [AddDaySafe](#AddDaySafe)
|
||||||
|
- [AddMonthSafe](#AddMonthSafe)
|
||||||
|
- [AddYearSafe](#AddYearSafe)
|
||||||
- [BeginOfMinute](#BeginOfMinute)
|
- [BeginOfMinute](#BeginOfMinute)
|
||||||
- [BeginOfHour](#BeginOfHour)
|
- [BeginOfHour](#BeginOfHour)
|
||||||
- [BeginOfDay](#BeginOfDay)
|
- [BeginOfDay](#BeginOfDay)
|
||||||
@@ -111,7 +116,7 @@ import (
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func AddDay(t time.Time, day int64) time.Time
|
func AddDay(t time.Time, days int64) time.Time
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/dIGbs_uTdFa)</span></b>
|
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/dIGbs_uTdFa)</span></b>
|
||||||
@@ -126,20 +131,89 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
now := time.Now()
|
date, _ := time.Parse("2006-01-02 15:04:05", "2021-01-01 00:00:00")
|
||||||
|
|
||||||
tomorrow := datetime.AddDay(now, 1)
|
after1Day := datetime.AddDay(date, 1)
|
||||||
diff1 := tomorrow.Sub(now)
|
before1Day := datetime.AddDay(date, -1)
|
||||||
|
|
||||||
yesterday := datetime.AddDay(now, -1)
|
fmt.Println(after1Day.Format("2006-01-02 15:04:05"))
|
||||||
diff2 := yesterday.Sub(now)
|
fmt.Println(before1Day.Format("2006-01-02 15:04:05"))
|
||||||
|
|
||||||
fmt.Println(diff1)
|
|
||||||
fmt.Println(diff2)
|
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// 24h0m0s
|
// 2021-01-02 00:00:00
|
||||||
// -24h0m0s
|
// 2020-12-31 00:00:00
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="AddWeek">AddWeek</span>
|
||||||
|
|
||||||
|
<p>Add or sub weeks to time.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func AddWeek(t time.Time, weeks int64) time.Time
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block;">[Run](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
date, _ := time.Parse("2006-01-02", "2021-01-01")
|
||||||
|
|
||||||
|
after2Weeks := datetime.AddWeek(date, 2)
|
||||||
|
before2Weeks := datetime.AddWeek(date, -2)
|
||||||
|
|
||||||
|
fmt.Println(after2Weeks.Format("2006-01-02"))
|
||||||
|
fmt.Println(before2Weeks.Format("2006-01-02"))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2021-01-15
|
||||||
|
// 2020-12-18
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="AddMonth">AddMonth</span>
|
||||||
|
|
||||||
|
<p>Add or sub months to time.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func AddMonth(t time.Time, months int64) time.Time
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block;">[Run](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
date, _ := time.Parse("2006-01-02", "2021-01-01")
|
||||||
|
|
||||||
|
after2Months := datetime.AddMonth(date, 2)
|
||||||
|
before2Months := datetime.AddMonth(date, -2)
|
||||||
|
|
||||||
|
fmt.Println(after2Months.Format("2006-01-02"))
|
||||||
|
fmt.Println(before2Months.Format("2006-01-02"))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2021-03-01
|
||||||
|
// 2020-11-01
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -165,20 +239,17 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
now := time.Now()
|
date, _ := time.Parse("2006-01-02 15:04:05", "2021-01-01 00:00:00")
|
||||||
|
|
||||||
after2Hours := datetime.AddHour(now, 2)
|
after2Hours := datetime.AddHour(date, 2)
|
||||||
diff1 := after2Hours.Sub(now)
|
before2Hours := datetime.AddHour(date, -2)
|
||||||
|
|
||||||
before2Hours := datetime.AddHour(now, -2)
|
fmt.Println(after2Hours.Format("2006-01-02 15:04:05"))
|
||||||
diff2 := before2Hours.Sub(now)
|
fmt.Println(before2Hours.Format("2006-01-02 15:04:05"))
|
||||||
|
|
||||||
fmt.Println(diff1)
|
|
||||||
fmt.Println(diff2)
|
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// 2h0m0s
|
// 2021-01-01 02:00:00
|
||||||
// -2h0m0s
|
// 2020-12-31 22:00:00
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -204,20 +275,17 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
now := time.Now()
|
date, _ := time.Parse("2006-01-02 15:04:05", "2021-01-01 00:00:00")
|
||||||
|
|
||||||
after2Minutes := datetime.AddMinute(now, 2)
|
after2Minutes := datetime.AddMinute(date, 2)
|
||||||
diff1 := after2Minutes.Sub(now)
|
before2Minutes := datetime.AddMinute(date, -2)
|
||||||
|
|
||||||
before2Minutes := datetime.AddMinute(now, -2)
|
fmt.Println(after2Minutes.Format("2006-01-02 15:04:05"))
|
||||||
diff2 := before2Minutes.Sub(now)
|
fmt.Println(before2Minutes.Format("2006-01-02 15:04:05"))
|
||||||
|
|
||||||
fmt.Println(diff1)
|
|
||||||
fmt.Println(diff2)
|
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// 2m0s
|
// 2021-01-01 00:02:00
|
||||||
// -2m0s
|
// 2020-12-31 23:58:00
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -243,20 +311,137 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
now := time.Now()
|
date, _ := time.Parse("2006-01-02", "2021-01-01")
|
||||||
|
|
||||||
after1Year := datetime.AddYear(now, 1)
|
after2Years := AddYear(date, 2)
|
||||||
diff1 := after1Year.Sub(now)
|
before2Years := AddYear(date, -2)
|
||||||
|
|
||||||
before1Year := datetime.AddYear(now, -1)
|
fmt.Println(after2Years.Format("2006-01-02"))
|
||||||
diff2 := before1Year.Sub(now)
|
fmt.Println(before2Years.Format("2006-01-02"))
|
||||||
|
|
||||||
fmt.Println(diff1)
|
|
||||||
fmt.Println(diff2)
|
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// 8760h0m0s
|
// 2023-01-01
|
||||||
// -8760h0m0s
|
// 2019-01-01
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="AddDaySafe">AddDaySafe</span>
|
||||||
|
|
||||||
|
<p>Add or sub days to the time and ensure that the returned date does not exceed the valid date of the target year and month.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func AddDaySafe(t time.Time, days int) time.Time
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block;">[Run](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
leapYearDate1, _ := time.Parse("2006-01-02", "2024-02-29")
|
||||||
|
result1 := datetime.AddDaySafe(leapYearDate1, 1)
|
||||||
|
|
||||||
|
leapYearDate2, _ := time.Parse("2006-01-02", "2024-03-01")
|
||||||
|
result2 := datetime.AddDaySafe(leapYearDate2, -1)
|
||||||
|
|
||||||
|
nonLeapYearDate1, _ := time.Parse("2006-01-02", "2025-02-28")
|
||||||
|
result3 := datetime.AddDaySafe(nonLeapYearDate1, 1)
|
||||||
|
|
||||||
|
nonLeaYearDate2, _ := time.Parse("2006-01-02", "2025-03-01")
|
||||||
|
result4 := datetime.AddDaySafe(nonLeaYearDate2, -1)
|
||||||
|
|
||||||
|
fmt.Println(result1.Format("2006-01-02"))
|
||||||
|
fmt.Println(result2.Format("2006-01-02"))
|
||||||
|
fmt.Println(result3.Format("2006-01-02"))
|
||||||
|
fmt.Println(result4.Format("2006-01-02"))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2024-03-01
|
||||||
|
// 2024-02-29
|
||||||
|
// 2025-03-01
|
||||||
|
// 2025-02-28
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="AddMonthSafe">AddMonthSafe</span>
|
||||||
|
|
||||||
|
<p>Add or sub months to the time and ensure that the returned date does not exceed the valid date of the target year and month.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func AddMonthSafe(t time.Time, months int) time.Time
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block;">[Run](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
date1, _ := time.Parse("2006-01-02", "2025-01-31")
|
||||||
|
result1 := datetime.AddMonthSafe(date1, 1)
|
||||||
|
|
||||||
|
date2, _ := time.Parse("2006-01-02", "2024-02-29")
|
||||||
|
result2 := datetime.AddMonthSafe(date2, -1)
|
||||||
|
|
||||||
|
fmt.Println(result1.Format("2006-01-02"))
|
||||||
|
fmt.Println(result2.Format("2006-01-02"))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2025-02-28
|
||||||
|
// 2024-01-29
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="AddYearSafe">AddYearSafe</span>
|
||||||
|
|
||||||
|
<p>Add or sub years to the time and ensure that the returned date does not exceed the valid date of the target year and month.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func AddYearSafe(t time.Time, years int) time.Time
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block;">[Run](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
"github.com/duke-git/lancet/v2/datetime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
date, _ := time.Parse("2006-01-02", "2020-02-29")
|
||||||
|
|
||||||
|
result1 := datetime.AddYearSafe(date, 1)
|
||||||
|
result2 := datetime.AddYearSafe(date, -1)
|
||||||
|
|
||||||
|
fmt.Println(result1.Format("2006-01-02"))
|
||||||
|
fmt.Println(result2.Format("2006-01-02"))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2021-02-28
|
||||||
|
// 2019-02-28
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -1342,7 +1527,7 @@ import (
|
|||||||
func main() {
|
func main() {
|
||||||
result1 := datetime.NowDateOrTime("yyyy-mm-dd hh:mm:ss")
|
result1 := datetime.NowDateOrTime("yyyy-mm-dd hh:mm:ss")
|
||||||
|
|
||||||
result2 := datetime.NowDateOrTime("yyyy-mm-dd hh:mm:ss", "EST")
|
result2 := datetime.NowDateOrTime("yyyy-mm-dd hh:mm:ss", "EST")
|
||||||
|
|
||||||
fmt.Println(result1)
|
fmt.Println(result1)
|
||||||
fmt.Println(result2)
|
fmt.Println(result2)
|
||||||
|
|||||||
401
docs/en/api/packages/eventbus.md
Normal file
401
docs/en/api/packages/eventbus.md
Normal file
@@ -0,0 +1,401 @@
|
|||||||
|
# EventBus
|
||||||
|
|
||||||
|
EventBus is an event bus used for handling events within an application.
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## Source:
|
||||||
|
|
||||||
|
- [https://github.com/duke-git/lancet/blob/main/eventbus/eventbus.go](https://github.com/duke-git/lancet/blob/main/eventbus/eventbus.go)
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## Usage:
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## Index
|
||||||
|
|
||||||
|
- [NewEventBus](#NewEventBus)
|
||||||
|
- [Subscribe](#Subscribe)
|
||||||
|
- [Unsubscribe](#Unsubscribe)
|
||||||
|
- [Publish](#Publish)
|
||||||
|
- [ClearListeners](#ClearListeners)
|
||||||
|
- [ClearListenersByTopic](#ClearListenersByTopic)
|
||||||
|
- [GetListenersCount](#GetListenersCount)
|
||||||
|
- [GetAllListenersCount](#GetAllListenersCount)
|
||||||
|
- [GetEvents](#GetEvents)
|
||||||
|
- [SetErrorHandler](#SetErrorHandler)
|
||||||
|
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
### <span id="NewEventBus">NewEventBus</span>
|
||||||
|
|
||||||
|
<p>Create an EventBus instance.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewEventBus[T any]() *EventBus[T]
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block;">[Run](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
eb := eventbus.NewEventBus[int]()
|
||||||
|
|
||||||
|
receivedData := 0
|
||||||
|
listener := func(eventData int) {
|
||||||
|
receivedData = eventData
|
||||||
|
}
|
||||||
|
|
||||||
|
eb.Subscribe("event1", listener, false, 0, nil)
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
|
||||||
|
|
||||||
|
fmt.Println(receivedData)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Subscribe">Subscribe</span>
|
||||||
|
|
||||||
|
<p>Subscribes to an event with a specific event topic and listener function.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (eb *EventBus[T]) Subscribe(topic string, listener func(eventData T), async bool, priority int, filter func(eventData T) bool)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block;">[Run](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
eb := eventbus.NewEventBus[int]()
|
||||||
|
|
||||||
|
receivedData := 0
|
||||||
|
listener := func(eventData int) {
|
||||||
|
receivedData = eventData
|
||||||
|
}
|
||||||
|
|
||||||
|
filter := func(eventData int) bool {
|
||||||
|
return eventData == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
eb.Subscribe("event1", listener, false, 0, filter)
|
||||||
|
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 2})
|
||||||
|
|
||||||
|
fmt.Println(receivedData)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Unsubscribe">Unsubscribe</span>
|
||||||
|
|
||||||
|
<p>Unsubscribes from an event with a specific event topic and listener function.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (eb *EventBus[T]) Unsubscribe(topic string, listener func(eventData T))
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block;">[Run](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
eb := eventbus.NewEventBus[int]()
|
||||||
|
|
||||||
|
receivedData := 0
|
||||||
|
listener := func(eventData int) {
|
||||||
|
receivedData = eventData
|
||||||
|
}
|
||||||
|
|
||||||
|
eb.Subscribe("event1", listener, false, 0, nil)
|
||||||
|
eb.Unsubscribe("event1", listener)
|
||||||
|
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
|
||||||
|
|
||||||
|
fmt.Println(receivedData)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Publish">Publish</span>
|
||||||
|
|
||||||
|
<p>Publishes an event with a specific event topic and data payload.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (eb *EventBus[T]) Publish(event Event[T])
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block;">[Run](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
eb := eventbus.NewEventBus[int]()
|
||||||
|
|
||||||
|
eb.Subscribe("event1", func(eventData int) {
|
||||||
|
fmt.Println(eventData)
|
||||||
|
}, false, 0, nil)
|
||||||
|
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="ClearListeners">ClearListeners</span>
|
||||||
|
|
||||||
|
<p>Clears all the listeners.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (eb *EventBus[T]) ClearListeners()
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block;">[Run](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
eb := eventbus.NewEventBus[int]()
|
||||||
|
|
||||||
|
receivedData := 0
|
||||||
|
listener := func(eventData int) {
|
||||||
|
receivedData = eventData
|
||||||
|
}
|
||||||
|
|
||||||
|
eb.Subscribe("event1", listener, false, 0, nil)
|
||||||
|
eb.ClearListeners()
|
||||||
|
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
|
||||||
|
|
||||||
|
fmt.Println(receivedData)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="ClearListenersByTopic">ClearListenersByTopic</span>
|
||||||
|
|
||||||
|
<p>Clears all the listeners by topic.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (eb *EventBus[T]) ClearListenersByTopic(topic string)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block;">[Run](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
eb := eventbus.NewEventBus[int]()
|
||||||
|
|
||||||
|
receivedData := 0
|
||||||
|
listener := func(eventData int) {
|
||||||
|
receivedData = eventData
|
||||||
|
}
|
||||||
|
|
||||||
|
eb.Subscribe("event1", listener, false, 0, nil)
|
||||||
|
eb.ClearListenersByTopic("event1")
|
||||||
|
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
|
||||||
|
|
||||||
|
fmt.Println(receivedData)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="GetListenersCount">GetListenersCount</span>
|
||||||
|
|
||||||
|
<p>Returns the number of listeners for a specific event topic.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (eb *EventBus[T]) GetListenersCount(topic string) int
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block;">[Run](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
eb := eventbus.NewEventBus[int]()
|
||||||
|
|
||||||
|
eb.Subscribe("event1", func(eventData int) {}, false, 0, nil)
|
||||||
|
eb.Subscribe("event1", func(eventData int) {}, false, 0, nil)
|
||||||
|
|
||||||
|
count := eb.GetListenersCount("event1")
|
||||||
|
|
||||||
|
fmt.Println(count)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="GetAllListenersCount">GetAllListenersCount</span>
|
||||||
|
|
||||||
|
<p>Returns the total number of all listeners.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (eb *EventBus[T]) GetAllListenersCount() int
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block;">[Run](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
eb := eventbus.NewEventBus[int]()
|
||||||
|
|
||||||
|
eb.Subscribe("event1", func(eventData int) {}, false, 0, nil)
|
||||||
|
eb.Subscribe("event2", func(eventData int) {}, false, 0, nil)
|
||||||
|
|
||||||
|
count := eb.GetAllListenersCount()
|
||||||
|
|
||||||
|
fmt.Println(count)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="GetEvents">GetEvents</span>
|
||||||
|
|
||||||
|
<p>Returns all the events topics.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (eb *EventBus[T]) GetEvents() []string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block;">[Run](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
eb := eventbus.NewEventBus[int]()
|
||||||
|
|
||||||
|
eb.Subscribe("event1", func(eventData int) {}, false, 0, nil)
|
||||||
|
eb.Subscribe("event2", func(eventData int) {}, false, 0, nil)
|
||||||
|
|
||||||
|
events := eb.GetEvents()
|
||||||
|
|
||||||
|
for _, event := range events {
|
||||||
|
fmt.Println(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// event1
|
||||||
|
// event2
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="SetErrorHandler">SetErrorHandler</span>
|
||||||
|
|
||||||
|
<p>Sets the error handler function.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (eb *EventBus[T]) SetErrorHandler(handler func(err error))
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block;">[Run](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/eventbus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
eb := eventbus.NewEventBus[int]()
|
||||||
|
|
||||||
|
eb.SetErrorHandler(func(err error) {
|
||||||
|
fmt.Println(err)
|
||||||
|
})
|
||||||
|
|
||||||
|
eb.Subscribe("event1", func(eventData int) {
|
||||||
|
panic("error")
|
||||||
|
}, false, 0, nil)
|
||||||
|
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// error
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -70,6 +70,7 @@ import (
|
|||||||
- [FlatMap](#FlatMap)
|
- [FlatMap](#FlatMap)
|
||||||
- [Merge](#Merge)
|
- [Merge](#Merge)
|
||||||
- [Reverse](#Reverse)
|
- [Reverse](#Reverse)
|
||||||
|
- [ReverseCopy](#ReverseCopy)
|
||||||
- [Reduce<sup>deprecated</sup>](#Reduce)
|
- [Reduce<sup>deprecated</sup>](#Reduce)
|
||||||
- [ReduceConcurrent](#ReduceConcurrent)
|
- [ReduceConcurrent](#ReduceConcurrent)
|
||||||
- [ReduceBy](#ReduceBy)
|
- [ReduceBy](#ReduceBy)
|
||||||
@@ -78,6 +79,7 @@ import (
|
|||||||
- [ReplaceAll](#ReplaceAll)
|
- [ReplaceAll](#ReplaceAll)
|
||||||
- [Repeat](#Repeat)
|
- [Repeat](#Repeat)
|
||||||
- [Shuffle](#Shuffle)
|
- [Shuffle](#Shuffle)
|
||||||
|
- [ShuffleCopy](#ShuffleCopy)
|
||||||
- [IsAscending](#IsAscending)
|
- [IsAscending](#IsAscending)
|
||||||
- [IsDescending](#IsDescending)
|
- [IsDescending](#IsDescending)
|
||||||
- [IsSorted](#IsSorted)
|
- [IsSorted](#IsSorted)
|
||||||
@@ -842,7 +844,7 @@ func main() {
|
|||||||
|
|
||||||
### <span id="EqualUnordered">EqualUnordered</span>
|
### <span id="EqualUnordered">EqualUnordered</span>
|
||||||
|
|
||||||
<p>Checks if two slices are equal: the same length and all elements' value are equal (unordered).</p>
|
<p>Checks if two slices are equal: the same length and all elements value are equal (unordered).</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
@@ -1756,6 +1758,38 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="ReverseCopy">ReverseCopy</span>
|
||||||
|
|
||||||
|
<p>Return a new slice of element order is reversed to the given slice.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReverseCopy[T any](slice []T) []T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block;">[Run](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
strs := []string{"a", "b", "c", "d"}
|
||||||
|
|
||||||
|
reversedStrs := slice.ReverseCopy(strs)
|
||||||
|
|
||||||
|
fmt.Println(reversedStrs)
|
||||||
|
fmt.Println(strs)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [d c b a]
|
||||||
|
// [a b c d]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="Reduce">Reduce</span>
|
### <span id="Reduce">Reduce</span>
|
||||||
|
|
||||||
<p>Reduce slice.</p>
|
<p>Reduce slice.</p>
|
||||||
@@ -2018,6 +2052,37 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="ShuffleCopy">ShuffleCopy</span>
|
||||||
|
|
||||||
|
<p>Return a new slice with elements shuffled.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ShuffleCopy[T any](slice []T) []T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block;">[Run](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
nums := []int{1, 2, 3, 4, 5}
|
||||||
|
result := slice.ShuffleCopy(nums)
|
||||||
|
|
||||||
|
fmt.Println(result)
|
||||||
|
fmt.Println(nums)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [3 1 5 4 2] (random order)
|
||||||
|
// [1 2 3 4 5]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="IsAscending">IsAscending</span>
|
### <span id="IsAscending">IsAscending</span>
|
||||||
|
|
||||||
<p>Checks if a slice is ascending order.</p>
|
<p>Checks if a slice is ascending order.</p>
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ import (
|
|||||||
- [IsIp](#IsIp)
|
- [IsIp](#IsIp)
|
||||||
- [IsIpV4](#IsIpV4)
|
- [IsIpV4](#IsIpV4)
|
||||||
- [IsIpV6](#IsIpV6)
|
- [IsIpV6](#IsIpV6)
|
||||||
|
- [IsIpPort](#IsIpPort)
|
||||||
- [IsStrongPassword](#IsStrongPassword)
|
- [IsStrongPassword](#IsStrongPassword)
|
||||||
- [IsUrl](#IsUrl)
|
- [IsUrl](#IsUrl)
|
||||||
- [IsWeakPassword](#IsWeakPassword)
|
- [IsWeakPassword](#IsWeakPassword)
|
||||||
@@ -992,6 +993,43 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="IsIpPort">IsIpPort</span>
|
||||||
|
|
||||||
|
<p>Check if the string is ip:port</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func IsIpPort(str string) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block">[Run](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/validator"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := validator.IsIpPort("127.0.0.1:8080")
|
||||||
|
result2 := validator.IsIpPort("[0:0:0:0:0:0:0:1]:8080")
|
||||||
|
result3 := validator.IsIpPort(":8080")
|
||||||
|
result4 := validator.IsIpPort("::0:0:0:0:")
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="IsStrongPassword">IsStrongPassword</span>
|
### <span id="IsStrongPassword">IsStrongPassword</span>
|
||||||
|
|
||||||
<p>Check if the string is strong password (alpha(lower+upper) + number + special chars(!@#$%^&*()?gt<)).</p>
|
<p>Check if the string is strong password (alpha(lower+upper) + number + special chars(!@#$%^&*()?gt<)).</p>
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ type EventListener[T any] struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewEventBus creates a new EventBus.
|
// NewEventBus creates a new EventBus.
|
||||||
|
// Play: todo
|
||||||
func NewEventBus[T any]() *EventBus[T] {
|
func NewEventBus[T any]() *EventBus[T] {
|
||||||
return &EventBus[T]{
|
return &EventBus[T]{
|
||||||
listeners: sync.Map{},
|
listeners: sync.Map{},
|
||||||
@@ -40,6 +41,7 @@ func NewEventBus[T any]() *EventBus[T] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Subscribe subscribes to an event with a specific event topic and listener function.
|
// Subscribe subscribes to an event with a specific event topic and listener function.
|
||||||
|
// Play: todo
|
||||||
func (eb *EventBus[T]) Subscribe(topic string, listener func(eventData T), async bool, priority int, filter func(eventData T) bool) {
|
func (eb *EventBus[T]) Subscribe(topic string, listener func(eventData T), async bool, priority int, filter func(eventData T) bool) {
|
||||||
eb.mu.Lock()
|
eb.mu.Lock()
|
||||||
defer eb.mu.Unlock()
|
defer eb.mu.Unlock()
|
||||||
@@ -63,6 +65,7 @@ func (eb *EventBus[T]) Subscribe(topic string, listener func(eventData T), async
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Unsubscribe unsubscribes from an event with a specific event topic and listener function.
|
// Unsubscribe unsubscribes from an event with a specific event topic and listener function.
|
||||||
|
// Play: todo
|
||||||
func (eb *EventBus[T]) Unsubscribe(topic string, listener func(eventData T)) {
|
func (eb *EventBus[T]) Unsubscribe(topic string, listener func(eventData T)) {
|
||||||
eb.mu.Lock()
|
eb.mu.Lock()
|
||||||
defer eb.mu.Unlock()
|
defer eb.mu.Unlock()
|
||||||
@@ -86,6 +89,7 @@ func (eb *EventBus[T]) Unsubscribe(topic string, listener func(eventData T)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Publish publishes an event with a specific event topic and data payload.
|
// Publish publishes an event with a specific event topic and data payload.
|
||||||
|
// Play: todo
|
||||||
func (eb *EventBus[T]) Publish(event Event[T]) {
|
func (eb *EventBus[T]) Publish(event Event[T]) {
|
||||||
eb.mu.RLock()
|
eb.mu.RLock()
|
||||||
defer eb.mu.RUnlock()
|
defer eb.mu.RUnlock()
|
||||||
@@ -126,6 +130,7 @@ func (eb *EventBus[T]) SetErrorHandler(handler func(err error)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ClearListeners clears all the listeners.
|
// ClearListeners clears all the listeners.
|
||||||
|
// Play: todo
|
||||||
func (eb *EventBus[T]) ClearListeners() {
|
func (eb *EventBus[T]) ClearListeners() {
|
||||||
eb.mu.Lock()
|
eb.mu.Lock()
|
||||||
defer eb.mu.Unlock()
|
defer eb.mu.Unlock()
|
||||||
@@ -134,6 +139,7 @@ func (eb *EventBus[T]) ClearListeners() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ClearListenersByTopic clears all the listeners by topic.
|
// ClearListenersByTopic clears all the listeners by topic.
|
||||||
|
// Play: todo
|
||||||
func (eb *EventBus[T]) ClearListenersByTopic(topic string) {
|
func (eb *EventBus[T]) ClearListenersByTopic(topic string) {
|
||||||
eb.mu.Lock()
|
eb.mu.Lock()
|
||||||
defer eb.mu.Unlock()
|
defer eb.mu.Unlock()
|
||||||
@@ -142,6 +148,7 @@ func (eb *EventBus[T]) ClearListenersByTopic(topic string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetListenersCount returns the number of listeners for a specific event topic.
|
// GetListenersCount returns the number of listeners for a specific event topic.
|
||||||
|
// Play: todo
|
||||||
func (eb *EventBus[T]) GetListenersCount(topic string) int {
|
func (eb *EventBus[T]) GetListenersCount(topic string) int {
|
||||||
eb.mu.RLock()
|
eb.mu.RLock()
|
||||||
defer eb.mu.RUnlock()
|
defer eb.mu.RUnlock()
|
||||||
@@ -156,6 +163,7 @@ func (eb *EventBus[T]) GetListenersCount(topic string) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetAllListenersCount returns the total number of listeners.
|
// GetAllListenersCount returns the total number of listeners.
|
||||||
|
// Play: todo
|
||||||
func (eb *EventBus[T]) GetAllListenersCount() int {
|
func (eb *EventBus[T]) GetAllListenersCount() int {
|
||||||
eb.mu.RLock()
|
eb.mu.RLock()
|
||||||
defer eb.mu.RUnlock()
|
defer eb.mu.RUnlock()
|
||||||
@@ -170,6 +178,7 @@ func (eb *EventBus[T]) GetAllListenersCount() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetEvents returns all the events topics.
|
// GetEvents returns all the events topics.
|
||||||
|
// Play: todo
|
||||||
func (eb *EventBus[T]) GetEvents() []string {
|
func (eb *EventBus[T]) GetEvents() []string {
|
||||||
eb.mu.RLock()
|
eb.mu.RLock()
|
||||||
defer eb.mu.RUnlock()
|
defer eb.mu.RUnlock()
|
||||||
|
|||||||
229
eventbus/eventbus_example_test.go
Normal file
229
eventbus/eventbus_example_test.go
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
package eventbus
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ExampleEventBus_Subscribe() {
|
||||||
|
eb := NewEventBus[string]()
|
||||||
|
eb.Subscribe("event1", func(eventData string) {
|
||||||
|
fmt.Println(eventData)
|
||||||
|
}, false, 0, nil)
|
||||||
|
|
||||||
|
eb.Publish(Event[string]{Topic: "event1", Payload: "hello"})
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// hello
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleEventBus_Unsubscribe() {
|
||||||
|
eb := NewEventBus[int]()
|
||||||
|
|
||||||
|
receivedData := 0
|
||||||
|
listener := func(eventData int) {
|
||||||
|
receivedData = eventData
|
||||||
|
}
|
||||||
|
|
||||||
|
eb.Subscribe("event1", listener, false, 0, nil)
|
||||||
|
eb.Unsubscribe("event1", listener)
|
||||||
|
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
|
||||||
|
|
||||||
|
fmt.Println(receivedData)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleEventBus_Subscribe_withFilter() {
|
||||||
|
eb := NewEventBus[int]()
|
||||||
|
|
||||||
|
receivedData := 0
|
||||||
|
listener := func(eventData int) {
|
||||||
|
receivedData = eventData
|
||||||
|
}
|
||||||
|
|
||||||
|
filter := func(eventData int) bool {
|
||||||
|
return eventData == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
eb.Subscribe("event1", listener, false, 0, filter)
|
||||||
|
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 2})
|
||||||
|
|
||||||
|
fmt.Println(receivedData)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleEventBus_Subscribe_withPriority() {
|
||||||
|
eb := NewEventBus[int]()
|
||||||
|
|
||||||
|
eb.Subscribe("event1", func(eventData int) {
|
||||||
|
fmt.Println(eventData)
|
||||||
|
}, false, 0, nil)
|
||||||
|
|
||||||
|
eb.Subscribe("event1", func(eventData int) {
|
||||||
|
fmt.Println(eventData)
|
||||||
|
}, false, 1, nil)
|
||||||
|
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1
|
||||||
|
// 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleEventBus_Subscribe_async() {
|
||||||
|
eb := NewEventBus[int]()
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
wg.Add(1)
|
||||||
|
|
||||||
|
eb.Subscribe("event1", func(eventData int) {
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
fmt.Println(eventData)
|
||||||
|
wg.Done()
|
||||||
|
}, true, 1, nil)
|
||||||
|
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleEventBus_Publish() {
|
||||||
|
eb := NewEventBus[int]()
|
||||||
|
|
||||||
|
eb.Subscribe("event1", func(eventData int) {
|
||||||
|
fmt.Println(eventData)
|
||||||
|
}, false, 0, nil)
|
||||||
|
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleEventBus() {
|
||||||
|
eb := NewEventBus[int]()
|
||||||
|
|
||||||
|
receivedData := 0
|
||||||
|
listener := func(eventData int) {
|
||||||
|
receivedData = eventData
|
||||||
|
}
|
||||||
|
|
||||||
|
eb.Subscribe("event1", listener, false, 0, nil)
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
|
||||||
|
|
||||||
|
fmt.Println(receivedData)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleEventBus_ClearListeners() {
|
||||||
|
eb := NewEventBus[int]()
|
||||||
|
|
||||||
|
receivedData := 0
|
||||||
|
listener := func(eventData int) {
|
||||||
|
receivedData = eventData
|
||||||
|
}
|
||||||
|
|
||||||
|
eb.Subscribe("event1", listener, false, 0, nil)
|
||||||
|
eb.ClearListeners()
|
||||||
|
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
|
||||||
|
|
||||||
|
fmt.Println(receivedData)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleEventBus_ClearListenersByTopic() {
|
||||||
|
eb := NewEventBus[int]()
|
||||||
|
|
||||||
|
receivedData := 0
|
||||||
|
listener := func(eventData int) {
|
||||||
|
receivedData = eventData
|
||||||
|
}
|
||||||
|
|
||||||
|
eb.Subscribe("event1", listener, false, 0, nil)
|
||||||
|
eb.ClearListenersByTopic("event1")
|
||||||
|
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
|
||||||
|
|
||||||
|
fmt.Println(receivedData)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleEventBus_GetListenersCount() {
|
||||||
|
eb := NewEventBus[int]()
|
||||||
|
|
||||||
|
eb.Subscribe("event1", func(eventData int) {}, false, 0, nil)
|
||||||
|
eb.Subscribe("event1", func(eventData int) {}, false, 0, nil)
|
||||||
|
|
||||||
|
count := eb.GetListenersCount("event1")
|
||||||
|
|
||||||
|
fmt.Println(count)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleEventBus_SetErrorHandler() {
|
||||||
|
eb := NewEventBus[int]()
|
||||||
|
|
||||||
|
eb.SetErrorHandler(func(err error) {
|
||||||
|
fmt.Println(err)
|
||||||
|
})
|
||||||
|
|
||||||
|
eb.Subscribe("event1", func(eventData int) {
|
||||||
|
panic("error")
|
||||||
|
}, false, 0, nil)
|
||||||
|
|
||||||
|
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// error
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleEventBus_GetAllListenersCount() {
|
||||||
|
|
||||||
|
eb := NewEventBus[int]()
|
||||||
|
|
||||||
|
eb.Subscribe("event1", func(eventData int) {}, false, 0, nil)
|
||||||
|
eb.Subscribe("event2", func(eventData int) {}, false, 0, nil)
|
||||||
|
|
||||||
|
count := eb.GetAllListenersCount()
|
||||||
|
|
||||||
|
fmt.Println(count)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleEventBus_GetEvents() {
|
||||||
|
eb := NewEventBus[int]()
|
||||||
|
|
||||||
|
eb.Subscribe("event1", func(eventData int) {}, false, 0, nil)
|
||||||
|
eb.Subscribe("event2", func(eventData int) {}, false, 0, nil)
|
||||||
|
|
||||||
|
events := eb.GetEvents()
|
||||||
|
|
||||||
|
for _, event := range events {
|
||||||
|
fmt.Println(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// event1
|
||||||
|
// event2
|
||||||
|
}
|
||||||
@@ -41,9 +41,9 @@ func TestEventBus_Unsubscribe(t *testing.T) {
|
|||||||
assert.Equal(0, receivedData)
|
assert.Equal(0, receivedData)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEventBus_Subscribe_WithFilter(t *testing.T) {
|
func TestEventBus_Subscribe_withFilter(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
assert := internal.NewAssert(t, "TestEventBus_Subscribe_WithFilter")
|
assert := internal.NewAssert(t, "TestEventBus_Subscribe_withFilter")
|
||||||
|
|
||||||
eb := NewEventBus[int]()
|
eb := NewEventBus[int]()
|
||||||
|
|
||||||
@@ -64,9 +64,9 @@ func TestEventBus_Subscribe_WithFilter(t *testing.T) {
|
|||||||
assert.Equal(1, receivedData)
|
assert.Equal(1, receivedData)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEventBus_Subscribe_WithPriority(t *testing.T) {
|
func TestEventBus_Subscribe_withPriority(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
assert := internal.NewAssert(t, "TestEventBus_Subscribe_WithPriority")
|
assert := internal.NewAssert(t, "TestEventBus_Subscribe_withPriority")
|
||||||
|
|
||||||
eb := NewEventBus[int]()
|
eb := NewEventBus[int]()
|
||||||
|
|
||||||
@@ -87,9 +87,9 @@ func TestEventBus_Subscribe_WithPriority(t *testing.T) {
|
|||||||
assert.Equal([]int{2, 1}, receivedData)
|
assert.Equal([]int{2, 1}, receivedData)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEventBus_Subscribe_Async(t *testing.T) {
|
func TestEventBus_Subscribe_async(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
assert := internal.NewAssert(t, "TestEventBus_Subscribe_Async")
|
assert := internal.NewAssert(t, "TestEventBus_Subscribe_async")
|
||||||
|
|
||||||
eb := NewEventBus[string]()
|
eb := NewEventBus[string]()
|
||||||
|
|
||||||
@@ -215,6 +215,5 @@ func TestEventBus_GetEvents(t *testing.T) {
|
|||||||
events := eb.GetEvents()
|
events := eb.GetEvents()
|
||||||
|
|
||||||
assert.Equal(2, len(events))
|
assert.Equal(2, len(events))
|
||||||
assert.Equal("event1", events[0])
|
assert.EqualValues([]string{"event1", "event2"}, events)
|
||||||
assert.Equal("event2", events[1])
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,10 +145,14 @@ func CeilToString[T constraints.Float | constraints.Integer](x T, n int) string
|
|||||||
|
|
||||||
// Max return max value of numbers.
|
// Max return max value of numbers.
|
||||||
// Play: https://go.dev/play/p/cN8DHI0rTkH
|
// Play: https://go.dev/play/p/cN8DHI0rTkH
|
||||||
func Max[T constraints.Integer | constraints.Float](numbers ...T) T {
|
func Max[T constraints.Ordered](items ...T) T {
|
||||||
max := numbers[0]
|
if len(items) < 1 {
|
||||||
|
panic("mathutil.Max: empty list")
|
||||||
|
}
|
||||||
|
|
||||||
for _, v := range numbers {
|
max := items[0]
|
||||||
|
|
||||||
|
for _, v := range items {
|
||||||
if max < v {
|
if max < v {
|
||||||
max = v
|
max = v
|
||||||
}
|
}
|
||||||
@@ -181,10 +185,14 @@ func MaxBy[T any](slice []T, comparator func(T, T) bool) T {
|
|||||||
|
|
||||||
// Min return min value of numbers.
|
// Min return min value of numbers.
|
||||||
// Play: https://go.dev/play/p/21BER_mlGUj
|
// Play: https://go.dev/play/p/21BER_mlGUj
|
||||||
func Min[T constraints.Integer | constraints.Float](numbers ...T) T {
|
func Min[T constraints.Ordered](items ...T) T {
|
||||||
min := numbers[0]
|
if len(items) < 1 {
|
||||||
|
panic("mathutil.min: empty list")
|
||||||
|
}
|
||||||
|
|
||||||
for _, v := range numbers {
|
min := items[0]
|
||||||
|
|
||||||
|
for _, v := range items {
|
||||||
if min > v {
|
if min > v {
|
||||||
min = v
|
min = v
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ func TestMax(t *testing.T) {
|
|||||||
assert.Equal(0, Max(0, 0))
|
assert.Equal(0, Max(0, 0))
|
||||||
assert.Equal(3, Max(1, 2, 3))
|
assert.Equal(3, Max(1, 2, 3))
|
||||||
assert.Equal(1.4, Max(1.2, 1.4, 1.1, 1.4))
|
assert.Equal(1.4, Max(1.2, 1.4, 1.1, 1.4))
|
||||||
|
assert.Equal("abc", Max("a", "ab", "abc"))
|
||||||
|
|
||||||
type Integer int
|
type Integer int
|
||||||
assert.Equal(Integer(1), Max(Integer(1), Integer(0)))
|
assert.Equal(Integer(1), Max(Integer(1), Integer(0)))
|
||||||
@@ -212,6 +213,8 @@ func TestMin(t *testing.T) {
|
|||||||
assert.Equal(0, Min(0, 0))
|
assert.Equal(0, Min(0, 0))
|
||||||
assert.Equal(1, Min(1, 2, 3))
|
assert.Equal(1, Min(1, 2, 3))
|
||||||
assert.Equal(1.1, Min(1.2, 1.4, 1.1, 1.4))
|
assert.Equal(1.1, Min(1.2, 1.4, 1.1, 1.4))
|
||||||
|
|
||||||
|
assert.Equal("a", Min("a", "ab", "abc"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMinBy(t *testing.T) {
|
func TestMinBy(t *testing.T) {
|
||||||
|
|||||||
@@ -1002,7 +1002,19 @@ func Reverse[T any](slice []T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shuffle the slice.
|
// ReverseCopy return a new slice of element order is reversed to the given slice.
|
||||||
|
// Play: todo
|
||||||
|
func ReverseCopy[T any](slice []T) []T {
|
||||||
|
result := make([]T, len(slice))
|
||||||
|
|
||||||
|
for i, j := 0, len(slice)-1; i < len(slice); i, j = i+1, j-1 {
|
||||||
|
result[i] = slice[j]
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shuffle return a new slice with elements shuffled.
|
||||||
// Play: https://go.dev/play/p/YHvhnWGU3Ge
|
// Play: https://go.dev/play/p/YHvhnWGU3Ge
|
||||||
func Shuffle[T any](slice []T) []T {
|
func Shuffle[T any](slice []T) []T {
|
||||||
rand.Seed(time.Now().UnixNano())
|
rand.Seed(time.Now().UnixNano())
|
||||||
@@ -1014,6 +1026,20 @@ func Shuffle[T any](slice []T) []T {
|
|||||||
return slice
|
return slice
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ShuffleCopy return a new slice with elements shuffled.
|
||||||
|
// Play: todo
|
||||||
|
func ShuffleCopy[T any](slice []T) []T {
|
||||||
|
result := make([]T, len(slice))
|
||||||
|
copy(result, slice)
|
||||||
|
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
rand.Shuffle(len(result), func(i, j int) {
|
||||||
|
result[i], result[j] = result[j], result[i]
|
||||||
|
})
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
// IsAscending checks if a slice is ascending order.
|
// IsAscending checks if a slice is ascending order.
|
||||||
// Play: https://go.dev/play/p/9CtsFjet4SH
|
// Play: https://go.dev/play/p/9CtsFjet4SH
|
||||||
func IsAscending[T constraints.Ordered](slice []T) bool {
|
func IsAscending[T constraints.Ordered](slice []T) bool {
|
||||||
|
|||||||
@@ -937,6 +937,41 @@ func ExampleReverse() {
|
|||||||
// [d c b a]
|
// [d c b a]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleReverseCopy() {
|
||||||
|
strs := []string{"a", "b", "c", "d"}
|
||||||
|
|
||||||
|
reversedStrs := ReverseCopy(strs)
|
||||||
|
|
||||||
|
fmt.Println(reversedStrs)
|
||||||
|
fmt.Println(strs)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [d c b a]
|
||||||
|
// [a b c d]
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleShuffle() {
|
||||||
|
strs := []string{"a", "b", "c", "d"}
|
||||||
|
Shuffle(strs)
|
||||||
|
|
||||||
|
fmt.Println(len(strs))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 4
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleShuffleCopy() {
|
||||||
|
strs := []string{"a", "b", "c", "d"}
|
||||||
|
shuffledStrs := ShuffleCopy(strs)
|
||||||
|
|
||||||
|
fmt.Println(len(shuffledStrs))
|
||||||
|
fmt.Println(strs)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 4
|
||||||
|
// [a b c d]
|
||||||
|
}
|
||||||
|
|
||||||
func ExampleIsAscending() {
|
func ExampleIsAscending() {
|
||||||
|
|
||||||
result1 := IsAscending([]int{1, 2, 3, 4, 5})
|
result1 := IsAscending([]int{1, 2, 3, 4, 5})
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -1114,6 +1115,17 @@ func TestReverse(t *testing.T) {
|
|||||||
assert.Equal([]string{"e", "d", "c", "b", "a"}, s2)
|
assert.Equal([]string{"e", "d", "c", "b", "a"}, s2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReverseCopy(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
assert := internal.NewAssert(t, "TestReverseCopy")
|
||||||
|
|
||||||
|
numbers := []int{1, 2, 3, 4, 5}
|
||||||
|
reversedNumbers := ReverseCopy(numbers)
|
||||||
|
|
||||||
|
assert.Equal([]int{5, 4, 3, 2, 1}, reversedNumbers)
|
||||||
|
assert.Equal([]int{1, 2, 3, 4, 5}, numbers)
|
||||||
|
}
|
||||||
|
|
||||||
func TestDifference(t *testing.T) {
|
func TestDifference(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
@@ -1329,6 +1341,18 @@ func TestShuffle(t *testing.T) {
|
|||||||
assert.Equal(5, len(result))
|
assert.Equal(5, len(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestShuffleCopy(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
assert := internal.NewAssert(t, "TestShuffleCopy")
|
||||||
|
|
||||||
|
numbers := []int{1, 2, 3, 4, 5}
|
||||||
|
result := ShuffleCopy(numbers)
|
||||||
|
|
||||||
|
assert.Equal(5, len(result))
|
||||||
|
assert.Equal([]int{1, 2, 3, 4, 5}, numbers)
|
||||||
|
}
|
||||||
|
|
||||||
func TestIndexOf(t *testing.T) {
|
func TestIndexOf(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
@@ -1794,6 +1818,8 @@ func TestFilterConcurrent(t *testing.T) {
|
|||||||
nums := []int{1, 2, 3, 4, 5, 6}
|
nums := []int{1, 2, 3, 4, 5, 6}
|
||||||
expected := []int{4, 5, 6}
|
expected := []int{4, 5, 6}
|
||||||
actual := FilterConcurrent(nums, func(_, n int) bool { return n > 3 }, 4)
|
actual := FilterConcurrent(nums, func(_, n int) bool { return n > 3 }, 4)
|
||||||
|
sort.Ints(actual)
|
||||||
|
sort.Ints(expected)
|
||||||
assert.Equal(expected, actual)
|
assert.Equal(expected, actual)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -207,6 +207,18 @@ func IsIp(ipstr string) bool {
|
|||||||
return ip != nil
|
return ip != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsIpPort check if the string is ip:port.
|
||||||
|
// Play:
|
||||||
|
func IsIpPort(str string) bool {
|
||||||
|
host, port, err := net.SplitHostPort(str)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
ip := net.ParseIP(host)
|
||||||
|
return ip != nil && IsPort(port)
|
||||||
|
}
|
||||||
|
|
||||||
// IsIpV4 check if the string is a ipv4 address.
|
// IsIpV4 check if the string is a ipv4 address.
|
||||||
// Play: https://go.dev/play/p/zBGT99EjaIu
|
// Play: https://go.dev/play/p/zBGT99EjaIu
|
||||||
func IsIpV4(ipstr string) bool {
|
func IsIpV4(ipstr string) bool {
|
||||||
|
|||||||
@@ -348,6 +348,24 @@ func ExampleIsIp() {
|
|||||||
// false
|
// false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleIsIpPort() {
|
||||||
|
result1 := IsIpPort("127.0.0.1:8080")
|
||||||
|
result2 := IsIpPort("[0:0:0:0:0:0:0:1]:8080")
|
||||||
|
result3 := IsIpPort(":8080")
|
||||||
|
result4 := IsIpPort("::0:0:0:0:")
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
|
||||||
func ExampleIsIpV4() {
|
func ExampleIsIpV4() {
|
||||||
result1 := IsIpV4("127.0.0.1")
|
result1 := IsIpV4("127.0.0.1")
|
||||||
result2 := IsIpV4("::0:0:0:0:0:0:1")
|
result2 := IsIpV4("::0:0:0:0:0:0:1")
|
||||||
|
|||||||
@@ -225,6 +225,23 @@ func TestIsIp(t *testing.T) {
|
|||||||
assert.Equal(false, IsIp("127"))
|
assert.Equal(false, IsIp("127"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIsIpPort(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
assert := internal.NewAssert(t, "TestIsIpPort")
|
||||||
|
|
||||||
|
assert.Equal(true, IsIpPort("[0:0:0:0:0:0:0:1]:8080")) // valid IPv6 and port
|
||||||
|
assert.Equal(true, IsIpPort("127.0.0.1:8080")) // valid IP and port
|
||||||
|
|
||||||
|
assert.Equal(false, IsIpPort("")) // empty string
|
||||||
|
assert.Equal(false, IsIpPort(":8080")) // only port
|
||||||
|
assert.Equal(false, IsIpPort("127.0.0.1")) // valid IP without port
|
||||||
|
assert.Equal(false, IsIpPort("0:0:0:0:0:0:0:1")) // valid IPv6 without port
|
||||||
|
assert.Equal(false, IsIpPort("256.256.256.256:8080")) // invalid IP with valid port
|
||||||
|
assert.Equal(false, IsIpPort("256.256.256.256:abc")) // invalid IP and invalid port
|
||||||
|
assert.Equal(false, IsIpPort("127.0.0.1:70000")) // valid IP with invalid port
|
||||||
|
}
|
||||||
|
|
||||||
func TestIsIpV4(t *testing.T) {
|
func TestIsIpV4(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
@@ -315,7 +332,7 @@ func TestIsChinesePhone(t *testing.T) {
|
|||||||
|
|
||||||
assert.Equal(true, IsChinesePhone("010-32116675"))
|
assert.Equal(true, IsChinesePhone("010-32116675"))
|
||||||
assert.Equal(true, IsChinesePhone("0464-8756213"))
|
assert.Equal(true, IsChinesePhone("0464-8756213"))
|
||||||
assert.Equal(true, IsChinesePhone("0731-82251545")) //长沙晚报电话
|
assert.Equal(true, IsChinesePhone("0731-82251545")) // 长沙晚报电话
|
||||||
assert.Equal(false, IsChinesePhone("123-87562"))
|
assert.Equal(false, IsChinesePhone("123-87562"))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user