mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-17 19:22:28 +08:00
Compare commits
41 Commits
ea0f96a8c0
...
v2.1.15
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8bf0786abe | ||
|
|
61cb8395e3 | ||
|
|
dde8a41daf | ||
|
|
d7518e01af | ||
|
|
be9fa7acaa | ||
|
|
2629a731cc | ||
|
|
54c7f90b7f | ||
|
|
770bc88b88 | ||
|
|
4cc1722f81 | ||
|
|
d0260b2841 | ||
|
|
57bd64cae7 | ||
|
|
c383719496 | ||
|
|
4b196a72b1 | ||
|
|
888381a06c | ||
|
|
a554eb7ef4 | ||
|
|
26ff90122b | ||
|
|
75b27c6540 | ||
|
|
a7e77fa98d | ||
|
|
abf392117a | ||
|
|
d231d9f572 | ||
|
|
97447d058e | ||
|
|
040e112aa6 | ||
|
|
afb021b4b5 | ||
|
|
5075774000 | ||
|
|
6bba44dc50 | ||
|
|
422022c74d | ||
|
|
87fcf97e2d | ||
|
|
05d1f348d4 | ||
|
|
6f2f1f3004 | ||
|
|
9cd9d1aeb5 | ||
|
|
71b27c0aa9 | ||
|
|
09a379ec6d | ||
|
|
b4b9b03835 | ||
|
|
48c7794b01 | ||
|
|
8e3911833d | ||
|
|
ebe494051b | ||
|
|
c35bda6a65 | ||
|
|
1fe4cdc429 | ||
|
|
6a79e322e3 | ||
|
|
17e8d2bb6d | ||
|
|
325be0d6a1 |
53
README.md
53
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)
|
||||||
@@ -24,7 +24,7 @@ English | [简体中文](./README_zh-CN.md)
|
|||||||
## Feature
|
## Feature
|
||||||
|
|
||||||
- 👏 Comprehensive, efficient and reusable.
|
- 👏 Comprehensive, efficient and reusable.
|
||||||
- 💪 300+ go util functions, support string, slice, datetime, net, crypt...
|
- 💪 400+ go util functions, support string, slice, datetime, net, crypt...
|
||||||
- 💅 Only depend on the go standard library.
|
- 💅 Only depend on the go standard library.
|
||||||
- 🌍 Unit test for every exported function.
|
- 🌍 Unit test for every exported function.
|
||||||
|
|
||||||
@@ -38,10 +38,10 @@ English | [简体中文](./README_zh-CN.md)
|
|||||||
go get github.com/duke-git/lancet/v2 // will install latest version of v2.x.x
|
go get github.com/duke-git/lancet/v2 // will install latest version of v2.x.x
|
||||||
```
|
```
|
||||||
|
|
||||||
2. <b>For users who use version below go1.18, you should install v1.x.x. The latest of v1.x.x is v1.3.5. </b>
|
2. <b>For users who use version below go1.18, you should install v1.x.x. The latest of v1.x.x is v1.3.6. </b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
go get github.com/duke-git/lancet@v1.3.5 // below go1.18, install latest version of v1.x.x
|
go get github.com/duke-git/lancet@v1.3.6 // below go1.18, install latest version of v1.x.x
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@@ -246,6 +246,8 @@ import "github.com/duke-git/lancet/v2/convertor"
|
|||||||
- **<big>DecodeByte</big>** : decode byte slice data to target object.
|
- **<big>DecodeByte</big>** : decode byte slice data to target object.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#DecodeByte)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#DecodeByte)]
|
||||||
[[play](https://go.dev/play/p/zI6xsmuQRbn)]
|
[[play](https://go.dev/play/p/zI6xsmuQRbn)]
|
||||||
|
- **<big>DeepClone</big>** : creates a deep copy of passed item, can't clone unexported field of struct.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#DeepClone)]
|
||||||
|
|
||||||
### 5. Cryptor package is for data encryption and decryption.
|
### 5. Cryptor package is for data encryption and decryption.
|
||||||
|
|
||||||
@@ -832,9 +834,15 @@ import "github.com/duke-git/lancet/v2/slice"
|
|||||||
- **<big>DeleteAt</big>** : delete the element of slice from specific start index to end index - 1.
|
- **<big>DeleteAt</big>** : delete the element of slice from specific start index to end index - 1.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DeleteAt)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DeleteAt)]
|
||||||
[[play](https://go.dev/play/p/pJ-d6MUWcvK)]
|
[[play](https://go.dev/play/p/pJ-d6MUWcvK)]
|
||||||
- **<big>Drop</big>** : creates a slice with `n` elements dropped from the beginning when n > 0, or `n` elements dropped from the ending when n < 0.
|
- **<big>Drop</big>** : drop n elements from the start of a slice.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Drop)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Drop)]
|
||||||
[[play](https://go.dev/play/p/pJ-d6MUWcvK)]
|
[[play](https://go.dev/play/p/pJ-d6MUWcvK)]
|
||||||
|
- **<big>DropRight</big>** : drop n elements from the end of a slice.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DropRight)]
|
||||||
|
- **<big>DropWhile</big>** : drop n elements from the start of a slice while predicate function returns true.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DropWhile)]
|
||||||
|
- **<big>DropRightWhile</big>** : drop n elements from the end of a slice while predicate function returns true.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DropRightWhile)]
|
||||||
- **<big>Equal</big>** : checks if two slices are equal: the same length and all elements' order and value are equal.
|
- **<big>Equal</big>** : checks if two slices are equal: the same length and all elements' order and value are equal.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Equal)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Equal)]
|
||||||
[[play](https://go.dev/play/p/WcRQJ37ifPa)]
|
[[play](https://go.dev/play/p/WcRQJ37ifPa)]
|
||||||
@@ -910,6 +918,14 @@ 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/slice.md#Shuffle)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Shuffle)]
|
||||||
[[play](https://go.dev/play/p/YHvhnWGU3Ge)]
|
[[play](https://go.dev/play/p/YHvhnWGU3Ge)]
|
||||||
|
- **<big>IsAscending</big>** : Checks if a slice is ascending order.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice.md#IsAscending)]
|
||||||
|
- **<big>IsDescending</big>** : Checks if a slice is descending order.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice.md#IsDescending)]
|
||||||
|
- **<big>IsSorted</big>** : Checks if a slice is sorted (ascending or descending).
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice.md#IsSorted)]
|
||||||
|
- **<big>IsSortedByKey</big>** : Checks if a slice is sorted by iteratee function.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice.md#IsSortedByKey)]
|
||||||
- **<big>Sort</big>** : sorts a slice of any ordered type(number or string).
|
- **<big>Sort</big>** : sorts a slice of any ordered type(number or string).
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Sort)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Sort)]
|
||||||
[[play](https://go.dev/play/p/V9AVjzf_4Fk)]
|
[[play](https://go.dev/play/p/V9AVjzf_4Fk)]
|
||||||
@@ -1160,9 +1176,32 @@ import "github.com/duke-git/lancet/v2/xerror"
|
|||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
- **<big>New</big>** : creates a new XError pointer instance with message.
|
||||||
- **<big>Unwrap</big>** : check if err is nil then it returns a valid value. If err is not nil, Unwrap panics with err.
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror.md#New)]
|
||||||
|
- **<big>Wrap</big>** : creates a new XError pointer instance based on error object, and add message.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror.md#Wrap)]
|
||||||
|
- **<big>Unwrap</big>** : returns unwrapped XError from err by errors.As. If no XError, returns nil.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror.md#Unwrap)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror.md#Unwrap)]
|
||||||
|
- **<big>XError_Wrap</big>** : creates a new XError and copy message and id to new one.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror.md#XError_Wrap)]
|
||||||
|
- **<big>XError_Unwrap</big>** : Compatible with github.com/pkg/errors.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror.md#XError_Unwrap)]
|
||||||
|
- **<big>XError_With</big>** : adds key and value related to the XError object.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror.md#XError_With)]
|
||||||
|
- **<big>XError_Id</big>** : sets XError object id to check equality in XError.Is.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror.md#XError_Id)]
|
||||||
|
- **<big>XError_Is</big>** : checks if target error is XError and Error.id of two errors are matched.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror.md#XError_Is)]
|
||||||
|
- **<big>XError_Values</big>** : returns map of key and value that is set by XError.With function.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror.md#XError_Values)]
|
||||||
|
- **<big>XError_StackTrace</big>** : returns stack trace which is compatible with pkg/errors.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror.md#XError_StackTrace)]
|
||||||
|
- **<big>XError_Info</big>** : returns information of xerror, which can be printed.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror.md#XError_Info)]
|
||||||
|
- **<big>XError_Error</big>** : implements standard error interface.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror.md#XError_Error)]
|
||||||
|
- **<big>TryUnwrap</big>** : check if err is nil then it returns a valid value. If err is not nil, TryUnwrap panics with err.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror.md#TryUnwrap)]
|
||||||
[[play](https://go.dev/play/p/w84d7Mb3Afk)]
|
[[play](https://go.dev/play/p/w84d7Mb3Afk)]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
## 特性
|
## 特性
|
||||||
|
|
||||||
- 👏 全面、高效、可复用
|
- 👏 全面、高效、可复用
|
||||||
- 💪 300+常用 go 工具函数,支持 string、slice、datetime、net、crypt...
|
- 💪 400+常用 go 工具函数,支持 string、slice、datetime、net、crypt...
|
||||||
- 💅 只依赖 go 标准库
|
- 💅 只依赖 go 标准库
|
||||||
- 🌍 所有导出函数单元测试覆盖率 100%
|
- 🌍 所有导出函数单元测试覆盖率 100%
|
||||||
|
|
||||||
@@ -37,10 +37,10 @@
|
|||||||
go get github.com/duke-git/lancet/v2 //安装v2最新版本v2.x.x
|
go get github.com/duke-git/lancet/v2 //安装v2最新版本v2.x.x
|
||||||
```
|
```
|
||||||
|
|
||||||
2. <b>使用 go1.18 以下版本的用户,必须安装 v1.x.x。目前最新的 v1 版本是 v1.3.5。</b>
|
2. <b>使用 go1.18 以下版本的用户,必须安装 v1.x.x。目前最新的 v1 版本是 v1.3.6。</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
go get github.com/duke-git/lancet@v1.3.5 // 使用go1.18以下版本, 必须安装v1.x.x版本
|
go get github.com/duke-git/lancet@v1.3.6 // 使用go1.18以下版本, 必须安装v1.x.x版本
|
||||||
```
|
```
|
||||||
|
|
||||||
## 用法
|
## 用法
|
||||||
@@ -51,7 +51,7 @@ lancet 是以包的结构组织代码的,使用时需要导入相应的包名
|
|||||||
import "github.com/duke-git/lancet/v2/strutil"
|
import "github.com/duke-git/lancet/v2/strutil"
|
||||||
```
|
```
|
||||||
|
|
||||||
## 例子
|
## 示例
|
||||||
|
|
||||||
此处以字符串工具函数 Reverse(逆序字符串)为例,需要导入 strutil 包:
|
此处以字符串工具函数 Reverse(逆序字符串)为例,需要导入 strutil 包:
|
||||||
|
|
||||||
@@ -245,6 +245,9 @@ import "github.com/duke-git/lancet/v2/convertor"
|
|||||||
- **<big>DecodeByte</big>** : 解码字节切片到目标对象,目标对象需要传入一个指针实例。
|
- **<big>DecodeByte</big>** : 解码字节切片到目标对象,目标对象需要传入一个指针实例。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#DecodeByte)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#DecodeByte)]
|
||||||
[[play](https://go.dev/play/p/zI6xsmuQRbn)]
|
[[play](https://go.dev/play/p/zI6xsmuQRbn)]
|
||||||
|
- **<big>DeepClone</big>** : 创建一个传入值的深拷贝, 无法克隆结构体的非导出字段。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#DeepClone)]
|
||||||
|
|
||||||
|
|
||||||
### 5. cryptor 加密包支持数据加密和解密,获取 md5,hash 值。支持 base64, md5, hmac, aes, des, rsa。
|
### 5. cryptor 加密包支持数据加密和解密,获取 md5,hash 值。支持 base64, md5, hmac, aes, des, rsa。
|
||||||
|
|
||||||
@@ -839,9 +842,15 @@ import "github.com/duke-git/lancet/v2/slice"
|
|||||||
- **<big>DeleteAt</big>** : 删除切片中指定开始索引到结束索引的元素。
|
- **<big>DeleteAt</big>** : 删除切片中指定开始索引到结束索引的元素。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#DeleteAt)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#DeleteAt)]
|
||||||
[[play](https://go.dev/play/p/pJ-d6MUWcvK)]
|
[[play](https://go.dev/play/p/pJ-d6MUWcvK)]
|
||||||
- **<big>Drop</big>** : 创建一个切片,当n > 0时从开头删除n个元素,或者当n < 0时从结尾删除n个元素。
|
- **<big>Drop</big>** : 从切片头部删除n个元素。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Drop)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Drop)]
|
||||||
[[play](https://go.dev/play/p/pJ-d6MUWcvK)]
|
[[play](https://go.dev/play/p/pJ-d6MUWcvK)]
|
||||||
|
- **<big>DropRight</big>** : 从切片尾部删除n个元素。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#DropRight)]
|
||||||
|
- **<big>DropWhile</big>** : 从切片的头部删除n个元素,这个n个元素满足predicate函数返回true。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#DropWhile)]
|
||||||
|
- **<big>DropRightWhile</big>** : 从切片的尾部删除n个元素,这个n个元素满足predicate函数返回true。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#DropRightWhile)]
|
||||||
- **<big>Equal</big>** : 检查两个切片是否相等,相等条件:切片长度相同,元素顺序和值都相同。
|
- **<big>Equal</big>** : 检查两个切片是否相等,相等条件:切片长度相同,元素顺序和值都相同。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Equal)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Equal)]
|
||||||
[[play](https://go.dev/play/p/WcRQJ37ifPa)]
|
[[play](https://go.dev/play/p/WcRQJ37ifPa)]
|
||||||
@@ -917,6 +926,14 @@ import "github.com/duke-git/lancet/v2/slice"
|
|||||||
- **<big>Shuffle</big>** : 随机打乱切片中的元素顺序。
|
- **<big>Shuffle</big>** : 随机打乱切片中的元素顺序。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Shuffle)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Shuffle)]
|
||||||
[[play](https://go.dev/play/p/YHvhnWGU3Ge)]
|
[[play](https://go.dev/play/p/YHvhnWGU3Ge)]
|
||||||
|
- **<big>IsAscending</big>** : 检查切片元素是否按升序排列。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#IsAscending)]
|
||||||
|
- **<big>IsDescending</big>** : 检查切片元素是否按降序排列。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#IsDescending)]
|
||||||
|
- **<big>IsSorted</big>** : 检查切片元素是否是有序的(升序或降序)。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#IsSorted)]
|
||||||
|
- **<big>IsSortedByKey</big>** : 通过iteratee函数,检查切片元素是否是有序的。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#IsSortedByKey)]
|
||||||
- **<big>Sort</big>** : 对任何有序类型(数字或字符串)的切片进行排序,使用快速排序算法。
|
- **<big>Sort</big>** : 对任何有序类型(数字或字符串)的切片进行排序,使用快速排序算法。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Sort)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Sort)]
|
||||||
[[play](https://go.dev/play/p/V9AVjzf_4Fk)]
|
[[play](https://go.dev/play/p/V9AVjzf_4Fk)]
|
||||||
@@ -1171,9 +1188,32 @@ import "github.com/duke-git/lancet/v2/xerror"
|
|||||||
|
|
||||||
#### 函数列表:
|
#### 函数列表:
|
||||||
|
|
||||||
|
- **<big>New</big>** : 创建XError对象实例。
|
||||||
- **<big>Unwrap</big>** : 检查error, 如果err为nil则展开,则它返回一个有效值,如果err不是nil则Unwrap使用err发生panic。
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#New)]
|
||||||
|
- **<big>Wrap</big>** : 根据error对象创建XError对象实例,可添加message。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#Wrap)]
|
||||||
|
- **<big>Unwrap</big>** : 从error对象中解构出XError。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#Unwrap)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#Unwrap)]
|
||||||
|
- **<big>XError_Wrap</big>** : 创建新的XError对象并将消息和id复制到新的对象中。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#XError_Wrap)]
|
||||||
|
- **<big>XError_Unwrap</big>** : 解构XEerror为error对象。适配github.com/pkg/errors。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#XError_Unwrap)]
|
||||||
|
- **<big>XError_With</big>** : 添加与XError对象的键和值。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#XError_With)]
|
||||||
|
- **<big>XError_Id</big>** : 设置XError对象的id。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#XError_Id)]
|
||||||
|
- **<big>XError_Is</big>** : 检查目标error是否为XError,两个错误中的error.id是否匹配。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#XError_Is)]
|
||||||
|
- **<big>XError_Values</big>** : 返回由With设置的键和值的映射。将合并所有XError键和值。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#XError_Values)]
|
||||||
|
- **<big>XError_StackTrace</big>** : 返回与pkg/error兼容的堆栈信息。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#XError_StackTrace)]
|
||||||
|
- **<big>XError_Info</big>** : 返回可打印的XError对象信息。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#XError_Info)]
|
||||||
|
- **<big>XError_Error</big>** : 实现标准库的error接口。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#XError_Error)]
|
||||||
|
- **<big>TryUnwrap</big>** : 检查error, 如果err为nil则展开,则它返回一个有效值,如果err不是nil则Unwrap使用err发生panic。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#TryUnwrap)]
|
||||||
[[play](https://go.dev/play/p/w84d7Mb3Afk)]
|
[[play](https://go.dev/play/p/w84d7Mb3Afk)]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -324,3 +324,19 @@ func DecodeByte(data []byte, target any) error {
|
|||||||
decoder := gob.NewDecoder(buffer)
|
decoder := gob.NewDecoder(buffer)
|
||||||
return decoder.Decode(target)
|
return decoder.Decode(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepClone creates a deep copy of passed item.
|
||||||
|
// can't clone unexported field of struct
|
||||||
|
// Play: todo
|
||||||
|
func DeepClone[T any](src T) T {
|
||||||
|
c := cloner{
|
||||||
|
ptrs: map[reflect.Type]map[uintptr]reflect.Value{},
|
||||||
|
}
|
||||||
|
result := c.clone(reflect.ValueOf(src))
|
||||||
|
if result.Kind() == reflect.Invalid {
|
||||||
|
var zeroValue T
|
||||||
|
return zeroValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.Interface().(T)
|
||||||
|
}
|
||||||
|
|||||||
@@ -252,3 +252,46 @@ func ExampleDecodeByte() {
|
|||||||
// Output:
|
// Output:
|
||||||
// abc
|
// abc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleDeepClone() {
|
||||||
|
type Struct struct {
|
||||||
|
Str string
|
||||||
|
Int int
|
||||||
|
Float float64
|
||||||
|
Bool bool
|
||||||
|
Nil interface{}
|
||||||
|
unexported string
|
||||||
|
}
|
||||||
|
|
||||||
|
cases := []interface{}{
|
||||||
|
true,
|
||||||
|
1,
|
||||||
|
0.1,
|
||||||
|
map[string]int{
|
||||||
|
"a": 1,
|
||||||
|
"b": 2,
|
||||||
|
},
|
||||||
|
&Struct{
|
||||||
|
Str: "test",
|
||||||
|
Int: 1,
|
||||||
|
Float: 0.1,
|
||||||
|
Bool: true,
|
||||||
|
Nil: nil,
|
||||||
|
// unexported: "can't be cloned",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range cases {
|
||||||
|
cloned := DeepClone(item)
|
||||||
|
|
||||||
|
isPointerEqual := &cloned == &item
|
||||||
|
fmt.Println(cloned, isPointerEqual)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true false
|
||||||
|
// 1 false
|
||||||
|
// 0.1 false
|
||||||
|
// map[a:1 b:2] false
|
||||||
|
// &{test 1 0.1 true <nil> } false
|
||||||
|
}
|
||||||
|
|||||||
216
convertor/convertor_internal.go
Normal file
216
convertor/convertor_internal.go
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
// Copyright 2023 dudaodong@gmail.com. All rights reserved.
|
||||||
|
// Use of this source code is governed by MIT license
|
||||||
|
|
||||||
|
// Package convertor implements some functions to convert data.
|
||||||
|
package convertor
|
||||||
|
|
||||||
|
import "reflect"
|
||||||
|
|
||||||
|
type cloner struct {
|
||||||
|
ptrs map[reflect.Type]map[uintptr]reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
// clone return a duplicate of passed item.
|
||||||
|
func (c *cloner) clone(v reflect.Value) reflect.Value {
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Invalid:
|
||||||
|
return reflect.ValueOf(nil)
|
||||||
|
|
||||||
|
// bool
|
||||||
|
case reflect.Bool:
|
||||||
|
return reflect.ValueOf(v.Bool())
|
||||||
|
|
||||||
|
//int
|
||||||
|
case reflect.Int:
|
||||||
|
return reflect.ValueOf(int(v.Int()))
|
||||||
|
case reflect.Int8:
|
||||||
|
return reflect.ValueOf(int8(v.Int()))
|
||||||
|
case reflect.Int16:
|
||||||
|
return reflect.ValueOf(int16(v.Int()))
|
||||||
|
case reflect.Int32:
|
||||||
|
return reflect.ValueOf(int32(v.Int()))
|
||||||
|
case reflect.Int64:
|
||||||
|
return reflect.ValueOf(v.Int())
|
||||||
|
|
||||||
|
// uint
|
||||||
|
case reflect.Uint:
|
||||||
|
return reflect.ValueOf(uint(v.Uint()))
|
||||||
|
case reflect.Uint8:
|
||||||
|
return reflect.ValueOf(uint8(v.Uint()))
|
||||||
|
case reflect.Uint16:
|
||||||
|
return reflect.ValueOf(uint16(v.Uint()))
|
||||||
|
case reflect.Uint32:
|
||||||
|
return reflect.ValueOf(uint32(v.Uint()))
|
||||||
|
case reflect.Uint64:
|
||||||
|
return reflect.ValueOf(v.Uint())
|
||||||
|
|
||||||
|
// float
|
||||||
|
case reflect.Float32:
|
||||||
|
return reflect.ValueOf(float32(v.Float()))
|
||||||
|
case reflect.Float64:
|
||||||
|
return reflect.ValueOf(v.Float())
|
||||||
|
|
||||||
|
// complex
|
||||||
|
case reflect.Complex64:
|
||||||
|
return reflect.ValueOf(complex64(v.Complex()))
|
||||||
|
case reflect.Complex128:
|
||||||
|
return reflect.ValueOf(v.Complex())
|
||||||
|
|
||||||
|
// string
|
||||||
|
case reflect.String:
|
||||||
|
return reflect.ValueOf(v.String())
|
||||||
|
|
||||||
|
// array
|
||||||
|
case reflect.Array, reflect.Slice:
|
||||||
|
return c.cloneArray(v)
|
||||||
|
|
||||||
|
// map
|
||||||
|
case reflect.Map:
|
||||||
|
return c.cloneMap(v)
|
||||||
|
|
||||||
|
// Ptr
|
||||||
|
case reflect.Ptr:
|
||||||
|
return c.clonePtr(v)
|
||||||
|
|
||||||
|
// struct
|
||||||
|
case reflect.Struct:
|
||||||
|
return c.cloneStruct(v)
|
||||||
|
|
||||||
|
// func
|
||||||
|
case reflect.Func:
|
||||||
|
return v
|
||||||
|
|
||||||
|
// interface
|
||||||
|
case reflect.Interface:
|
||||||
|
return c.clone(v.Elem())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return reflect.Zero(v.Type())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cloner) cloneArray(v reflect.Value) reflect.Value {
|
||||||
|
if v.IsNil() {
|
||||||
|
return reflect.Zero(v.Type())
|
||||||
|
}
|
||||||
|
|
||||||
|
arr := reflect.MakeSlice(v.Type(), v.Len(), v.Len())
|
||||||
|
|
||||||
|
for i := 0; i < v.Len(); i++ {
|
||||||
|
val := c.clone(v.Index(i))
|
||||||
|
|
||||||
|
if val.IsValid() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
item := arr.Index(i)
|
||||||
|
if !item.CanSet() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
item.Set(val.Convert(item.Type()))
|
||||||
|
}
|
||||||
|
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cloner) cloneMap(v reflect.Value) reflect.Value {
|
||||||
|
if v.IsNil() {
|
||||||
|
return reflect.Zero(v.Type())
|
||||||
|
}
|
||||||
|
|
||||||
|
clonedMap := reflect.MakeMap(v.Type())
|
||||||
|
|
||||||
|
for _, key := range v.MapKeys() {
|
||||||
|
value := v.MapIndex(key)
|
||||||
|
clonedKey := c.clone(key)
|
||||||
|
clonedValue := c.clone(value)
|
||||||
|
|
||||||
|
if !isNillable(clonedKey) || !clonedKey.IsNil() {
|
||||||
|
clonedKey = clonedKey.Convert(key.Type())
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isNillable(clonedValue) || !clonedValue.IsNil()) && clonedValue.IsValid() {
|
||||||
|
clonedValue = clonedValue.Convert(value.Type())
|
||||||
|
}
|
||||||
|
|
||||||
|
if !clonedValue.IsValid() {
|
||||||
|
clonedValue = reflect.Zero(clonedMap.Type().Elem())
|
||||||
|
}
|
||||||
|
|
||||||
|
clonedMap.SetMapIndex(clonedKey, clonedValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
return clonedMap
|
||||||
|
}
|
||||||
|
|
||||||
|
func isNillable(v reflect.Value) bool {
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Chan, reflect.Interface, reflect.Ptr, reflect.Func:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cloner) clonePtr(v reflect.Value) reflect.Value {
|
||||||
|
if v.IsNil() {
|
||||||
|
return reflect.Zero(v.Type())
|
||||||
|
}
|
||||||
|
|
||||||
|
var newVal reflect.Value
|
||||||
|
|
||||||
|
if v.Elem().CanAddr() {
|
||||||
|
ptrs, exists := c.ptrs[v.Type()]
|
||||||
|
if exists {
|
||||||
|
if newVal, exists := ptrs[v.Elem().UnsafeAddr()]; exists {
|
||||||
|
return newVal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newVal = c.clone(v.Elem())
|
||||||
|
|
||||||
|
if v.Elem().CanAddr() {
|
||||||
|
ptrs, exists := c.ptrs[v.Type()]
|
||||||
|
if exists {
|
||||||
|
if newVal, exists := ptrs[v.Elem().UnsafeAddr()]; exists {
|
||||||
|
return newVal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clonedPtr := reflect.New(newVal.Type())
|
||||||
|
clonedPtr.Elem().Set(newVal)
|
||||||
|
|
||||||
|
return clonedPtr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cloner) cloneStruct(v reflect.Value) reflect.Value {
|
||||||
|
clonedStructPtr := reflect.New(v.Type())
|
||||||
|
clonedStruct := clonedStructPtr.Elem()
|
||||||
|
|
||||||
|
if v.CanAddr() {
|
||||||
|
ptrs := c.ptrs[clonedStructPtr.Type()]
|
||||||
|
if ptrs == nil {
|
||||||
|
ptrs = make(map[uintptr]reflect.Value)
|
||||||
|
c.ptrs[clonedStructPtr.Type()] = ptrs
|
||||||
|
}
|
||||||
|
ptrs[v.UnsafeAddr()] = clonedStructPtr
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < v.NumField(); i++ {
|
||||||
|
newStructValue := clonedStruct.Field(i)
|
||||||
|
if !newStructValue.CanSet() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
clonedVal := c.clone(v.Field(i))
|
||||||
|
if !clonedVal.IsValid() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
newStructValue.Set(clonedVal.Convert(newStructValue.Type()))
|
||||||
|
}
|
||||||
|
|
||||||
|
return clonedStruct
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package convertor
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -253,3 +254,47 @@ func TestDecodeByte(t *testing.T) {
|
|||||||
assert.IsNil(err)
|
assert.IsNil(err)
|
||||||
assert.Equal("abc", obj)
|
assert.Equal("abc", obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDeepClone(t *testing.T) {
|
||||||
|
// assert := internal.NewAssert(t, "TestDeepClone")
|
||||||
|
|
||||||
|
type Struct struct {
|
||||||
|
Str string
|
||||||
|
Int int
|
||||||
|
Float float64
|
||||||
|
Bool bool
|
||||||
|
Nil interface{}
|
||||||
|
unexported string
|
||||||
|
}
|
||||||
|
|
||||||
|
cases := []interface{}{
|
||||||
|
true,
|
||||||
|
1,
|
||||||
|
0.1,
|
||||||
|
map[string]int{
|
||||||
|
"a": 1,
|
||||||
|
"b": 2,
|
||||||
|
},
|
||||||
|
&Struct{
|
||||||
|
Str: "test",
|
||||||
|
Int: 1,
|
||||||
|
Float: 0.1,
|
||||||
|
Bool: true,
|
||||||
|
Nil: nil,
|
||||||
|
// unexported: "can't be cloned",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, item := range cases {
|
||||||
|
cloned := DeepClone(item)
|
||||||
|
|
||||||
|
t.Log(cloned)
|
||||||
|
if &cloned == &item {
|
||||||
|
t.Fatalf("[TestDeepClone case #%d failed]: equal pointer", i)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(item, cloned) {
|
||||||
|
t.Fatalf("[TestDeepClone case #%d failed] unequal objects", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ package cryptor
|
|||||||
|
|
||||||
import "bytes"
|
import "bytes"
|
||||||
|
|
||||||
func generateAesKey(key []byte) []byte {
|
func generateAesKey(key []byte, size int) []byte {
|
||||||
genKey := make([]byte, 16)
|
genKey := make([]byte, size)
|
||||||
copy(genKey, key)
|
copy(genKey, key)
|
||||||
for i := 16; i < len(key); {
|
for i := size; i < len(key); {
|
||||||
for j := 0; j < 16 && i < len(key); j, i = j+1, i+1 {
|
for j := 0; j < size && i < len(key); j, i = j+1, i+1 {
|
||||||
genKey[j] ^= key[i]
|
genKey[j] ^= key[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,11 @@ import (
|
|||||||
// len(key) should be 16, 24 or 32.
|
// len(key) should be 16, 24 or 32.
|
||||||
// Play: https://go.dev/play/p/jT5irszHx-j
|
// Play: https://go.dev/play/p/jT5irszHx-j
|
||||||
func AesEcbEncrypt(data, key []byte) []byte {
|
func AesEcbEncrypt(data, key []byte) []byte {
|
||||||
|
size := len(key)
|
||||||
|
if size != 16 && size != 24 && size != 32 {
|
||||||
|
panic("key length shoud be 16 or 24 or 32")
|
||||||
|
}
|
||||||
|
|
||||||
length := (len(data) + aes.BlockSize) / aes.BlockSize
|
length := (len(data) + aes.BlockSize) / aes.BlockSize
|
||||||
plain := make([]byte, length*aes.BlockSize)
|
plain := make([]byte, length*aes.BlockSize)
|
||||||
|
|
||||||
@@ -34,7 +39,7 @@ func AesEcbEncrypt(data, key []byte) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
encrypted := make([]byte, len(plain))
|
encrypted := make([]byte, len(plain))
|
||||||
cipher, _ := aes.NewCipher(generateAesKey(key))
|
cipher, _ := aes.NewCipher(generateAesKey(key, size))
|
||||||
|
|
||||||
for bs, be := 0, cipher.BlockSize(); bs <= len(data); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
|
for bs, be := 0, cipher.BlockSize(); bs <= len(data); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
|
||||||
cipher.Encrypt(encrypted[bs:be], plain[bs:be])
|
cipher.Encrypt(encrypted[bs:be], plain[bs:be])
|
||||||
@@ -47,7 +52,11 @@ func AesEcbEncrypt(data, key []byte) []byte {
|
|||||||
// len(key) should be 16, 24 or 32.
|
// len(key) should be 16, 24 or 32.
|
||||||
// Play: https://go.dev/play/p/jT5irszHx-j
|
// Play: https://go.dev/play/p/jT5irszHx-j
|
||||||
func AesEcbDecrypt(encrypted, key []byte) []byte {
|
func AesEcbDecrypt(encrypted, key []byte) []byte {
|
||||||
cipher, _ := aes.NewCipher(generateAesKey(key))
|
size := len(key)
|
||||||
|
if size != 16 && size != 24 && size != 32 {
|
||||||
|
panic("key length shoud be 16 or 24 or 32")
|
||||||
|
}
|
||||||
|
cipher, _ := aes.NewCipher(generateAesKey(key, size))
|
||||||
decrypted := make([]byte, len(encrypted))
|
decrypted := make([]byte, len(encrypted))
|
||||||
|
|
||||||
for bs, be := 0, cipher.BlockSize(); bs < len(encrypted); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
|
for bs, be := 0, cipher.BlockSize(); bs < len(encrypted); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ package datastructure
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/v2/iterator"
|
||||||
)
|
)
|
||||||
|
|
||||||
// List is a linear table, implemented with slice.
|
// List is a linear table, implemented with slice.
|
||||||
@@ -316,6 +318,43 @@ func (l *List[T]) Intersection(other *List[T]) *List[T] {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Difference returns the difference between two collections.
|
||||||
|
// return a list whose element in the original list, not in the given list.
|
||||||
|
func (l *List[T]) Difference(other *List[T]) *List[T] {
|
||||||
|
result := NewList(make([]T, 0))
|
||||||
|
|
||||||
|
intersectList := l.Intersection(other)
|
||||||
|
|
||||||
|
for _, v := range l.data {
|
||||||
|
if !intersectList.Contain(v) {
|
||||||
|
result.data = append(result.data, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// SymmetricDifference oppoiste operation of intersection function.
|
||||||
|
func (l *List[T]) SymmetricDifference(other *List[T]) *List[T] {
|
||||||
|
result := NewList(make([]T, 0))
|
||||||
|
|
||||||
|
intersectList := l.Intersection(other)
|
||||||
|
|
||||||
|
for _, v := range l.data {
|
||||||
|
if !intersectList.Contain(v) {
|
||||||
|
result.data = append(result.data, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range other.data {
|
||||||
|
if !intersectList.Contain(v) {
|
||||||
|
result.data = append(result.data, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
// SubList returns a sub list of the original list between the specified fromIndex, inclusive, and toIndex, exclusive.
|
// SubList returns a sub list of the original list between the specified fromIndex, inclusive, and toIndex, exclusive.
|
||||||
func (l *List[T]) SubList(fromIndex, toIndex int) *List[T] {
|
func (l *List[T]) SubList(fromIndex, toIndex int) *List[T] {
|
||||||
data := l.data[fromIndex:toIndex]
|
data := l.data[fromIndex:toIndex]
|
||||||
@@ -323,3 +362,57 @@ func (l *List[T]) SubList(fromIndex, toIndex int) *List[T] {
|
|||||||
copy(subList, data)
|
copy(subList, data)
|
||||||
return NewList(subList)
|
return NewList(subList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ForEach performs the given action for each element of the list.
|
||||||
|
func (l *List[T]) ForEach(consumer func(T)) {
|
||||||
|
for _, it := range l.data {
|
||||||
|
consumer(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RetainAll retains only the elements in this list that are contained in the given list.
|
||||||
|
func (l *List[T]) RetainAll(list *List[T]) bool {
|
||||||
|
return l.batchRemove(list, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteAll removes from this list all of its elements that are contained in the given list.
|
||||||
|
func (l *List[T]) DeleteAll(list *List[T]) bool {
|
||||||
|
return l.batchRemove(list, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *List[T]) batchRemove(list *List[T], complement bool) bool {
|
||||||
|
var (
|
||||||
|
w = 0
|
||||||
|
data = l.data
|
||||||
|
size = len(data)
|
||||||
|
)
|
||||||
|
|
||||||
|
for i := 0; i < size; i++ {
|
||||||
|
if list.Contain(data[i]) == complement {
|
||||||
|
data[w] = data[i]
|
||||||
|
w++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if w != size {
|
||||||
|
l.data = data[:w]
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterator returns an iterator over the elements in this list in proper sequence.
|
||||||
|
func (l *List[T]) Iterator() iterator.Iterator[T] {
|
||||||
|
return iterator.FromSlice(l.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListToMap convert a list to a map based on iteratee function.
|
||||||
|
func ListToMap[T any, K comparable, V any](list *List[T], iteratee func(T) (K, V)) map[K]V {
|
||||||
|
result := make(map[K]V, list.Size())
|
||||||
|
for _, item := range list.data {
|
||||||
|
k, v := iteratee(item)
|
||||||
|
result[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|||||||
@@ -328,6 +328,28 @@ func TestIntersection(t *testing.T) {
|
|||||||
assert.Equal(true, expected.Equal(list3))
|
assert.Equal(true, expected.Equal(list3))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDifference(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestDifference")
|
||||||
|
|
||||||
|
list1 := NewList([]int{1, 2, 3})
|
||||||
|
list2 := NewList([]int{1, 2, 4})
|
||||||
|
expected := NewList([]int{3})
|
||||||
|
|
||||||
|
list3 := list1.Difference(list2)
|
||||||
|
assert.Equal(true, expected.Equal(list3))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSymmetricDifference(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestSymmetricDifference")
|
||||||
|
|
||||||
|
list1 := NewList([]int{1, 2, 3})
|
||||||
|
list2 := NewList([]int{1, 2, 4})
|
||||||
|
expected := NewList([]int{3, 4})
|
||||||
|
|
||||||
|
list3 := list1.SymmetricDifference(list2)
|
||||||
|
assert.Equal(true, expected.Equal(list3))
|
||||||
|
}
|
||||||
|
|
||||||
func TestSubSlice(t *testing.T) {
|
func TestSubSlice(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestSubSlice")
|
assert := internal.NewAssert(t, "TestSubSlice")
|
||||||
|
|
||||||
@@ -357,3 +379,84 @@ func TestDeleteIf(t *testing.T) {
|
|||||||
assert.Equal([]int{2, 3, 4}, list.Data())
|
assert.Equal([]int{2, 3, 4}, list.Data())
|
||||||
assert.Equal(0, count)
|
assert.Equal(0, count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestForEach(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestForEach")
|
||||||
|
|
||||||
|
list := NewList([]int{1, 2, 3, 4})
|
||||||
|
|
||||||
|
rs := make([]int, 0)
|
||||||
|
list.ForEach(func(i int) {
|
||||||
|
rs = append(rs, i)
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal([]int{1, 2, 3, 4}, rs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRetainAll(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestRetainAll")
|
||||||
|
|
||||||
|
list := NewList([]int{1, 2, 3, 4})
|
||||||
|
list1 := NewList([]int{1, 2, 3, 4})
|
||||||
|
list2 := NewList([]int{1, 2, 3, 4})
|
||||||
|
|
||||||
|
retain := NewList([]int{1, 2})
|
||||||
|
retain1 := NewList([]int{2, 3})
|
||||||
|
retain2 := NewList([]int{1, 2, 5})
|
||||||
|
|
||||||
|
list.RetainAll(retain)
|
||||||
|
list1.RetainAll(retain1)
|
||||||
|
list2.RetainAll(retain2)
|
||||||
|
|
||||||
|
assert.Equal([]int{1, 2}, list.Data())
|
||||||
|
assert.Equal([]int{2, 3}, list1.Data())
|
||||||
|
assert.Equal([]int{1, 2}, list2.Data())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteAll(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestDeleteAll")
|
||||||
|
|
||||||
|
list := NewList([]int{1, 2, 3, 4})
|
||||||
|
list1 := NewList([]int{1, 2, 3, 4})
|
||||||
|
list2 := NewList([]int{1, 2, 3, 4})
|
||||||
|
|
||||||
|
del := NewList([]int{1})
|
||||||
|
del1 := NewList([]int{2, 3})
|
||||||
|
del2 := NewList([]int{1, 2, 5})
|
||||||
|
|
||||||
|
list.DeleteAll(del)
|
||||||
|
list1.DeleteAll(del1)
|
||||||
|
list2.DeleteAll(del2)
|
||||||
|
assert.Equal([]int{2, 3, 4}, list.Data())
|
||||||
|
assert.Equal([]int{1, 4}, list1.Data())
|
||||||
|
assert.Equal([]int{3, 4}, list2.Data())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIterator(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestIterator")
|
||||||
|
|
||||||
|
list := NewList([]int{1, 2, 3, 4})
|
||||||
|
|
||||||
|
iterator := list.Iterator()
|
||||||
|
|
||||||
|
rs := make([]int, 0)
|
||||||
|
for iterator.HasNext() {
|
||||||
|
item, _ := iterator.Next()
|
||||||
|
rs = append(rs, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal([]int{1, 2, 3, 4}, rs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListToMap(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "ListToMap")
|
||||||
|
|
||||||
|
list := NewList([]int{1, 2, 3, 4})
|
||||||
|
|
||||||
|
result := ListToMap(list, func(n int) (int, bool) {
|
||||||
|
return n, n > 1
|
||||||
|
})
|
||||||
|
expected := map[int]bool{1: false, 2: true, 3: true, 4: true}
|
||||||
|
|
||||||
|
assert.Equal(expected, result)
|
||||||
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ import (
|
|||||||
type Channel[T any] struct
|
type Channel[T any] struct
|
||||||
func NewChannel[T any]() *Channel[T]
|
func NewChannel[T any]() *Channel[T]
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -70,7 +70,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
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
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -122,7 +122,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (c *Channel[T]) FanIn(ctx context.Context, channels ...<-chan T) <-chan T
|
func (c *Channel[T]) FanIn(ctx context.Context, channels ...<-chan T) <-chan T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -161,7 +161,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (c *Channel[T]) Generate(ctx context.Context, values ...T) <-chan T
|
func (c *Channel[T]) Generate(ctx context.Context, values ...T) <-chan T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -199,7 +199,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (c *Channel[T]) Repeat(ctx context.Context, values ...T) <-chan T
|
func (c *Channel[T]) Repeat(ctx context.Context, values ...T) <-chan T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -238,7 +238,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (c *Channel[T]) RepeatFn(ctx context.Context, fn func() T) <-chan T
|
func (c *Channel[T]) RepeatFn(ctx context.Context, fn func() T) <-chan T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -279,7 +279,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (c *Channel[T]) Or(channels ...<-chan T) <-chan T
|
func (c *Channel[T]) Or(channels ...<-chan T) <-chan T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -322,7 +322,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (c *Channel[T]) OrDone(ctx context.Context, channel <-chan T) <-chan T
|
func (c *Channel[T]) OrDone(ctx context.Context, channel <-chan T) <-chan T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -360,7 +360,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (c *Channel[T]) Take(ctx context.Context, valueStream <-chan T, number int) <-chan T
|
func (c *Channel[T]) Take(ctx context.Context, valueStream <-chan T, number int) <-chan T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -406,7 +406,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (c *Channel[T]) Tee(ctx context.Context, in <-chan T) (<-chan T, <-chan T)
|
func (c *Channel[T]) Tee(ctx context.Context, in <-chan T) (<-chan T, <-chan T)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ slices和map的length大于0时,返回true,否则返回false<br/>
|
|||||||
```go
|
```go
|
||||||
func Bool[T any](value T) bool
|
func Bool[T any](value T) bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -109,7 +109,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func And[T, U any](a T, b U) bool
|
func And[T, U any](a T, b U) bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -135,7 +135,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Or[T, U any](a T, b U) bool
|
func Or[T, U any](a T, b U) bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -161,7 +161,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Xor[T, U any](a T, b U) bool
|
func Xor[T, U any](a T, b U) bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -187,7 +187,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Nor[T, U any](a T, b U) bool
|
func Nor[T, U any](a T, b U) bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -213,7 +213,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Xnor[T, U any](a T, b U) bool
|
func Xnor[T, U any](a T, b U) bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -239,7 +239,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Nand[T, U any](a T, b U) bool
|
func Nand[T, U any](a T, b U) bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -265,7 +265,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func TernaryOperator[T, U any](isTrue T, ifValue U, elseValue U) U
|
func TernaryOperator[T, U any](isTrue T, ifValue U, elseValue U) U
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
# Convertor
|
# Convertor
|
||||||
|
|
||||||
Package convertor contains some functions for data type convertion.
|
Package convertor contains some functions for data type convertion.
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Source:
|
## Source:
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/convertor/convertor.go](https://github.com/duke-git/lancet/blob/main/convertor/convertor.go)
|
- [https://github.com/duke-git/lancet/blob/main/convertor/convertor.go](https://github.com/duke-git/lancet/blob/main/convertor/convertor.go)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Usage:
|
## Usage:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/v2/convertor"
|
||||||
@@ -19,28 +21,31 @@ import (
|
|||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Index
|
## Index
|
||||||
- [ColorHexToRGB](#ColorHexToRGB)
|
|
||||||
- [ColorRGBToHex](#ColorRGBToHex)
|
- [ColorHexToRGB](#ColorHexToRGB)
|
||||||
- [ToBool](#ToBool)
|
- [ColorRGBToHex](#ColorRGBToHex)
|
||||||
- [ToBytes](#ToBytes)
|
- [ToBool](#ToBool)
|
||||||
- [ToChar](#ToChar)
|
- [ToBytes](#ToBytes)
|
||||||
- [ToChannel](#ToChannel)
|
- [ToChar](#ToChar)
|
||||||
- [ToFloat](#ToFloat)
|
- [ToChannel](#ToChannel)
|
||||||
- [ToInt](#ToInt)
|
- [ToFloat](#ToFloat)
|
||||||
- [ToJson](#ToJson)
|
- [ToInt](#ToInt)
|
||||||
- [ToMap](#ToMap)
|
- [ToJson](#ToJson)
|
||||||
- [ToPointer](#ToPointer)
|
- [ToMap](#ToMap)
|
||||||
- [ToString](#ToString)
|
- [ToPointer](#ToPointer)
|
||||||
- [StructToMap](#StructToMap)
|
- [ToString](#ToString)
|
||||||
- [MapToSlice](#MapToSlice)
|
- [StructToMap](#StructToMap)
|
||||||
- [EncodeByte](#EncodeByte)
|
- [MapToSlice](#MapToSlice)
|
||||||
- [DecodeByte](#DecodeByte)
|
- [EncodeByte](#EncodeByte)
|
||||||
|
- [DecodeByte](#DecodeByte)
|
||||||
|
- [DeepClone](#DeepClone)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
### <span id="ColorHexToRGB">ColorHexToRGB</span>
|
### <span id="ColorHexToRGB">ColorHexToRGB</span>
|
||||||
|
|
||||||
<p>Convert color hex to color rgb.</p>
|
<p>Convert color hex to color rgb.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -48,6 +53,7 @@ import (
|
|||||||
```go
|
```go
|
||||||
func ColorHexToRGB(colorHex string) (red, green, blue int)
|
func ColorHexToRGB(colorHex string) (red, green, blue int)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -78,6 +84,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ColorRGBToHex(red, green, blue int) string
|
func ColorRGBToHex(red, green, blue int) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -110,6 +117,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToBool(s string) (bool, error)
|
func ToBool(s string) (bool, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -150,6 +158,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToBytes(data any) ([]byte, error)
|
func ToBytes(data any) ([]byte, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -182,6 +191,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToChar(s string) []string
|
func ToChar(s string) []string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -217,6 +227,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToChannel[T any](array []T) <-chan T
|
func ToChannel[T any](array []T) <-chan T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -253,6 +264,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToFloat(value any) (float64, error)
|
func ToFloat(value any) (float64, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -297,6 +309,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToInt(value any) (int64, error)
|
func ToInt(value any) (int64, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -338,6 +351,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToJson(value any) (string, error)
|
func ToJson(value any) (string, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -372,6 +386,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToMap[T any, K comparable, V any](array []T, iteratee func(T) (K, V)) map[K]V
|
func ToMap[T any, K comparable, V any](array []T, iteratee func(T) (K, V)) map[K]V
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -412,6 +427,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToPointer[T any](value T) *T
|
func ToPointer[T any](value T) *T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -440,6 +456,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToString(value any) string
|
func ToString(value any) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -487,6 +504,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func StructToMap(value any) (map[string]any, error)
|
func StructToMap(value any) (map[string]any, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -524,6 +542,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func MapToSlice[T any, K comparable, V any](aMap map[K]V, iteratee func(K, V) T) []T
|
func MapToSlice[T any, K comparable, V any](aMap map[K]V, iteratee func(K, V) T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -544,7 +563,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="EncodeByte">EncodeByte</span>
|
### <span id="EncodeByte">EncodeByte</span>
|
||||||
|
|
||||||
<p>Encode data to byte slice.</p>
|
<p>Encode data to byte slice.</p>
|
||||||
@@ -554,6 +572,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func EncodeByte(data any) ([]byte, error)
|
func EncodeByte(data any) ([]byte, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -582,6 +601,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func DecodeByte(data []byte, target any) error
|
func DecodeByte(data []byte, target any) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -607,3 +627,68 @@ func main() {
|
|||||||
// abc
|
// abc
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="DeepClone">DeepClone</span>
|
||||||
|
|
||||||
|
<p>Creates a deep copy of passed item, can't clone unexported field of struct.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func DeepClone[T any](src T) T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
type Struct struct {
|
||||||
|
Str string
|
||||||
|
Int int
|
||||||
|
Float float64
|
||||||
|
Bool bool
|
||||||
|
Nil interface{}
|
||||||
|
unexported string
|
||||||
|
}
|
||||||
|
|
||||||
|
cases := []interface{}{
|
||||||
|
true,
|
||||||
|
1,
|
||||||
|
0.1,
|
||||||
|
map[string]int{
|
||||||
|
"a": 1,
|
||||||
|
"b": 2,
|
||||||
|
},
|
||||||
|
&Struct{
|
||||||
|
Str: "test",
|
||||||
|
Int: 1,
|
||||||
|
Float: 0.1,
|
||||||
|
Bool: true,
|
||||||
|
Nil: nil,
|
||||||
|
// unexported: "can't be cloned",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range cases {
|
||||||
|
cloned := convertor.DeepClone(item)
|
||||||
|
|
||||||
|
isPointerEqual := &cloned == &item
|
||||||
|
fmt.Println(cloned, isPointerEqual)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true false
|
||||||
|
// 1 false
|
||||||
|
// 0.1 false
|
||||||
|
// map[a:1 b:2] false
|
||||||
|
// &{test 1 0.1 true <nil> } false
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
# Convertor
|
# Convertor
|
||||||
convertor转换器包支持一些常见的数据类型转换
|
|
||||||
|
convertor 转换器包支持一些常见的数据类型转换
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 源码:
|
## 源码:
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/convertor/convertor.go](https://github.com/duke-git/lancet/blob/main/convertor/convertor.go)
|
- [https://github.com/duke-git/lancet/blob/main/convertor/convertor.go](https://github.com/duke-git/lancet/blob/main/convertor/convertor.go)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
@@ -21,29 +22,30 @@ import (
|
|||||||
|
|
||||||
## 目录
|
## 目录
|
||||||
|
|
||||||
- [ColorHexToRGB](#ColorHexToRGB)
|
- [ColorHexToRGB](#ColorHexToRGB)
|
||||||
- [ColorRGBToHex](#ColorRGBToHex)
|
- [ColorRGBToHex](#ColorRGBToHex)
|
||||||
- [ToBool](#ToBool)
|
- [ToBool](#ToBool)
|
||||||
- [ToBytes](#ToBytes)
|
- [ToBytes](#ToBytes)
|
||||||
- [ToChar](#ToChar)
|
- [ToChar](#ToChar)
|
||||||
- [ToChannel](#ToChannel)
|
- [ToChannel](#ToChannel)
|
||||||
- [ToFloat](#ToFloat)
|
- [ToFloat](#ToFloat)
|
||||||
- [ToInt](#ToInt)
|
- [ToInt](#ToInt)
|
||||||
- [ToJson](#ToJson)
|
- [ToJson](#ToJson)
|
||||||
- [ToMap](#ToMap)
|
- [ToMap](#ToMap)
|
||||||
- [ToPointer](#ToPointer)
|
- [ToPointer](#ToPointer)
|
||||||
- [ToString](#ToString)
|
- [ToString](#ToString)
|
||||||
- [StructToMap](#StructToMap)
|
- [StructToMap](#StructToMap)
|
||||||
- [MapToSlice](#MapToSlice)
|
- [MapToSlice](#MapToSlice)
|
||||||
- [EncodeByte](#EncodeByte)
|
- [EncodeByte](#EncodeByte)
|
||||||
- [DecodeByte](#DecodeByte)
|
- [DecodeByte](#DecodeByte)
|
||||||
|
- [DeepClone](#DeepClone)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 文档
|
## 文档
|
||||||
|
|
||||||
|
|
||||||
### <span id="ColorHexToRGB">ColorHexToRGB</span>
|
### <span id="ColorHexToRGB">ColorHexToRGB</span>
|
||||||
|
|
||||||
<p>颜色值十六进制转rgb。</p>
|
<p>颜色值十六进制转rgb。</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -51,6 +53,7 @@ import (
|
|||||||
```go
|
```go
|
||||||
func ColorHexToRGB(colorHex string) (red, green, blue int)
|
func ColorHexToRGB(colorHex string) (red, green, blue int)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -81,6 +84,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ColorRGBToHex(red, green, blue int) string
|
func ColorRGBToHex(red, green, blue int) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -113,6 +117,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToBool(s string) (bool, error)
|
func ToBool(s string) (bool, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -153,6 +158,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToBytes(data any) ([]byte, error)
|
func ToBytes(data any) ([]byte, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -185,6 +191,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToChar(s string) []string
|
func ToChar(s string) []string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -220,6 +227,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToChannel[T any](array []T) <-chan T
|
func ToChannel[T any](array []T) <-chan T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -256,6 +264,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToFloat(value any) (float64, error)
|
func ToFloat(value any) (float64, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -300,6 +309,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToInt(value any) (int64, error)
|
func ToInt(value any) (int64, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -341,6 +351,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToJson(value any) (string, error)
|
func ToJson(value any) (string, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -375,6 +386,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToMap[T any, K comparable, V any](array []T, iteratee func(T) (K, V)) map[K]V
|
func ToMap[T any, K comparable, V any](array []T, iteratee func(T) (K, V)) map[K]V
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -415,6 +427,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToPointer[T any](value T) *T
|
func ToPointer[T any](value T) *T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -443,6 +456,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToString(value any) string
|
func ToString(value any) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -490,6 +504,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func StructToMap(value any) (map[string]any, error)
|
func StructToMap(value any) (map[string]any, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -527,6 +542,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func MapToSlice[T any, K comparable, V any](aMap map[K]V, iteratee func(K, V) T) []T
|
func MapToSlice[T any, K comparable, V any](aMap map[K]V, iteratee func(K, V) T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -556,6 +572,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func EncodeByte(data any) ([]byte, error)
|
func EncodeByte(data any) ([]byte, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -584,6 +601,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func DecodeByte(data []byte, target any) error
|
func DecodeByte(data []byte, target any) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -609,3 +627,67 @@ func main() {
|
|||||||
// abc
|
// abc
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="DeepClone">DeepClone</span>
|
||||||
|
|
||||||
|
<p>创建一个传入值的深拷贝, 无法克隆结构体的非导出字段。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func DeepClone[T any](src T) T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
type Struct struct {
|
||||||
|
Str string
|
||||||
|
Int int
|
||||||
|
Float float64
|
||||||
|
Bool bool
|
||||||
|
Nil interface{}
|
||||||
|
unexported string
|
||||||
|
}
|
||||||
|
|
||||||
|
cases := []interface{}{
|
||||||
|
true,
|
||||||
|
1,
|
||||||
|
0.1,
|
||||||
|
map[string]int{
|
||||||
|
"a": 1,
|
||||||
|
"b": 2,
|
||||||
|
},
|
||||||
|
&Struct{
|
||||||
|
Str: "test",
|
||||||
|
Int: 1,
|
||||||
|
Float: 0.1,
|
||||||
|
Bool: true,
|
||||||
|
Nil: nil,
|
||||||
|
// unexported: "can't be cloned",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range cases {
|
||||||
|
cloned := convertor.DeepClone(item)
|
||||||
|
|
||||||
|
isPointerEqual := &cloned == &item
|
||||||
|
fmt.Println(cloned, isPointerEqual)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true false
|
||||||
|
// 1 false
|
||||||
|
// 0.1 false
|
||||||
|
// map[a:1 b:2] false
|
||||||
|
// &{test 1 0.1 true <nil> } false
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -46,7 +46,7 @@ import (
|
|||||||
func NewHashMap() *HashMap
|
func NewHashMap() *HashMap
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -72,7 +72,7 @@ func main() {
|
|||||||
func NewHashMapWithCapacity(size, capacity uint64) *HashMap
|
func NewHashMapWithCapacity(size, capacity uint64) *HashMap
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -98,7 +98,7 @@ func main() {
|
|||||||
func (hm *HashMap) Get(key any) any
|
func (hm *HashMap) Get(key any) any
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -126,7 +126,7 @@ func main() {
|
|||||||
func (hm *HashMap) Put(key any, value any) any
|
func (hm *HashMap) Put(key any, value any) any
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -155,7 +155,7 @@ func main() {
|
|||||||
func (hm *HashMap) Delete(key any)
|
func (hm *HashMap) Delete(key any)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -187,7 +187,7 @@ func main() {
|
|||||||
func (hm *HashMap) Contains(key any) bool
|
func (hm *HashMap) Contains(key any) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -217,7 +217,7 @@ func main() {
|
|||||||
func (hm *HashMap) Iterate(iteratee func(key, value any))
|
func (hm *HashMap) Iterate(iteratee func(key, value any))
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -252,7 +252,7 @@ func main() {
|
|||||||
func (hm *HashMap) Keys() []any
|
func (hm *HashMap) Keys() []any
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -284,7 +284,7 @@ func main() {
|
|||||||
func (hm *HashMap) Values() []any
|
func (hm *HashMap) Values() []any
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ type MaxHeap[T any] struct {
|
|||||||
}
|
}
|
||||||
func NewMaxHeap[T any](comparator lancetconstraints.Comparator) *MaxHeap[T]
|
func NewMaxHeap[T any](comparator lancetconstraints.Comparator) *MaxHeap[T]
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -89,7 +89,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (h *MaxHeap[T]) Push(value T)
|
func (h *MaxHeap[T]) Push(value T)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -136,7 +136,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (h *MaxHeap[T]) Pop() (T, bool)
|
func (h *MaxHeap[T]) Pop() (T, bool)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -184,7 +184,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (h *MaxHeap[T]) Peek() (T, bool)
|
func (h *MaxHeap[T]) Peek() (T, bool)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -232,7 +232,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (h *MaxHeap[T]) Data() []T
|
func (h *MaxHeap[T]) Data() []T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -277,7 +277,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (h *MaxHeap[T]) Size() int
|
func (h *MaxHeap[T]) Size() int
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -323,7 +323,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (h *MaxHeap[T]) PrintStructure()
|
func (h *MaxHeap[T]) PrintStructure()
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ type SinglyLink[T any] struct {
|
|||||||
}
|
}
|
||||||
func NewSinglyLink[T any]() *SinglyLink[T]
|
func NewSinglyLink[T any]() *SinglyLink[T]
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -107,7 +107,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *SinglyLink[T]) Values() []T
|
func (link *SinglyLink[T]) Values() []T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -139,7 +139,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *SinglyLink[T]) InsertAt(index int, value T)
|
func (link *SinglyLink[T]) InsertAt(index int, value T)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -174,7 +174,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *SinglyLink[T]) InsertAtHead(value T)
|
func (link *SinglyLink[T]) InsertAtHead(value T)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -206,7 +206,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *SinglyLink[T]) InsertAtTail(value T)
|
func (link *SinglyLink[T]) InsertAtTail(value T)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -237,7 +237,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *SinglyLink[T]) DeleteAt(index int)
|
func (link *SinglyLink[T]) DeleteAt(index int)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -271,7 +271,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *SinglyLink[T]) DeleteAtHead()
|
func (link *SinglyLink[T]) DeleteAtHead()
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -306,7 +306,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *SinglyLink[T]) DeleteAtTail()
|
func (link *SinglyLink[T]) DeleteAtTail()
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -339,7 +339,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *SinglyLink[T]) DeleteValue(value T)
|
func (link *SinglyLink[T]) DeleteValue(value T)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -373,7 +373,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *SinglyLink[T]) Reverse()
|
func (link *SinglyLink[T]) Reverse()
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -405,7 +405,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *SinglyLink[T]) GetMiddleNode() *datastructure.LinkNode[T]
|
func (link *SinglyLink[T]) GetMiddleNode() *datastructure.LinkNode[T]
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -437,7 +437,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *SinglyLink[T]) Size() int
|
func (link *SinglyLink[T]) Size() int
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -468,7 +468,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *SinglyLink[T]) IsEmpty() bool
|
func (link *SinglyLink[T]) IsEmpty() bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -500,7 +500,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *SinglyLink[T]) Clear()
|
func (link *SinglyLink[T]) Clear()
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -533,7 +533,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *SinglyLink[T]) Clear()
|
func (link *SinglyLink[T]) Clear()
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -576,7 +576,7 @@ type DoublyLink[T any] struct {
|
|||||||
}
|
}
|
||||||
func NewDoublyLink[T any]() *DoublyLink[T]
|
func NewDoublyLink[T any]() *DoublyLink[T]
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -602,7 +602,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *DoublyLink[T]) Values() []T
|
func (link *DoublyLink[T]) Values() []T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -634,7 +634,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *DoublyLink[T]) InsertAt(index int, value T)
|
func (link *DoublyLink[T]) InsertAt(index int, value T)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -669,7 +669,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *DoublyLink[T]) InsertAtHead(value T)
|
func (link *DoublyLink[T]) InsertAtHead(value T)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -701,7 +701,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *DoublyLink[T]) InsertAtTail(value T)
|
func (link *DoublyLink[T]) InsertAtTail(value T)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -732,7 +732,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *DoublyLink[T]) DeleteAt(index int)
|
func (link *DoublyLink[T]) DeleteAt(index int)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -766,7 +766,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *DoublyLink[T]) DeleteAtHead()
|
func (link *DoublyLink[T]) DeleteAtHead()
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -801,7 +801,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *DoublyLink[T]) DeleteAtTail()
|
func (link *DoublyLink[T]) DeleteAtTail()
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -835,7 +835,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *DoublyLink[T]) Reverse()
|
func (link *DoublyLink[T]) Reverse()
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -867,7 +867,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *DoublyLink[T]) GetMiddleNode() *datastructure.LinkNode[T]
|
func (link *DoublyLink[T]) GetMiddleNode() *datastructure.LinkNode[T]
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -899,7 +899,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *DoublyLink[T]) Size() int
|
func (link *DoublyLink[T]) Size() int
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -930,7 +930,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *DoublyLink[T]) IsEmpty() bool
|
func (link *DoublyLink[T]) IsEmpty() bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -962,7 +962,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *DoublyLink[T]) Clear()
|
func (link *DoublyLink[T]) Clear()
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -995,7 +995,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (link *DoublyLink[T]) Clear()
|
func (link *DoublyLink[T]) Clear()
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -47,6 +47,13 @@ import (
|
|||||||
- [Unique](#Unique)
|
- [Unique](#Unique)
|
||||||
- [Union](#Union)
|
- [Union](#Union)
|
||||||
- [Intersection](#Intersection)
|
- [Intersection](#Intersection)
|
||||||
|
- [Difference](#Difference)
|
||||||
|
- [SymmetricDifference](#SymmetricDifference)
|
||||||
|
- [RetainAll](#RetainAll)
|
||||||
|
- [DeleteAll](#DeleteAll)
|
||||||
|
- [ForEach](#ForEach)
|
||||||
|
- [Iterator](#Iterator)
|
||||||
|
- [ListToMap](#ListToMap)
|
||||||
- [SubList](#SubList)
|
- [SubList](#SubList)
|
||||||
- [DeleteIf](#DeleteIf)
|
- [DeleteIf](#DeleteIf)
|
||||||
|
|
||||||
@@ -62,7 +69,7 @@ NewList function return a list pointer</p>
|
|||||||
|
|
||||||
```go
|
```go
|
||||||
type List[T any] struct {
|
type List[T any] struct {
|
||||||
data []T
|
data []T
|
||||||
}
|
}
|
||||||
func NewList[T any](data []T) *List[T]
|
func NewList[T any](data []T) *List[T]
|
||||||
```
|
```
|
||||||
@@ -671,7 +678,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := make([]int, 0, 100)
|
data := make([]int, 0, 100)
|
||||||
|
|
||||||
li := list.NewList(data)
|
li := list.NewList(data)
|
||||||
|
|
||||||
@@ -828,6 +835,233 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Difference">Difference</span>
|
||||||
|
<p>Return a list whose element in the original list, not in the given list.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) Difference(other *List[T]) *List[T]
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
list1 := NewList([]int{1, 2, 3})
|
||||||
|
list2 := NewList([]int{1, 2, 4})
|
||||||
|
|
||||||
|
list3 := list1.Intersection(list2)
|
||||||
|
|
||||||
|
fmt.Println(list3.Data()) //3
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="SymmetricDifference">SymmetricDifference</span>
|
||||||
|
<p>Oppoiste operation of intersection function.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) SymmetricDifference(other *List[T]) *List[T]
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
list1 := NewList([]int{1, 2, 3})
|
||||||
|
list2 := NewList([]int{1, 2, 4})
|
||||||
|
|
||||||
|
list3 := list1.Intersection(list2)
|
||||||
|
|
||||||
|
fmt.Println(list3.Data()) //3, 4
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="RetainAll">RetainAll</span>
|
||||||
|
<p>Retains only the elements in this list that are contained in the given list.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) RetainAll(list *List[T]) bool
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
list := NewList([]int{1, 2, 3, 4})
|
||||||
|
list1 := NewList([]int{1, 2, 3, 4})
|
||||||
|
list2 := NewList([]int{1, 2, 3, 4})
|
||||||
|
|
||||||
|
retain := NewList([]int{1, 2})
|
||||||
|
retain1 := NewList([]int{2, 3})
|
||||||
|
retain2 := NewList([]int{1, 2, 5})
|
||||||
|
|
||||||
|
list.RetainAll(retain)
|
||||||
|
list1.RetainAll(retain1)
|
||||||
|
list2.RetainAll(retain2)
|
||||||
|
|
||||||
|
fmt.Println(list.Data()) //1, 2
|
||||||
|
fmt.Println(list1.Data()) //2, 3
|
||||||
|
fmt.Println(list2.Data()) //1, 2
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="DeleteAll">DeleteAll</span>
|
||||||
|
<p>Removes from this list all of its elements that are contained in the given list.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) DeleteAll(list *List[T]) bool
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
list := NewList([]int{1, 2, 3, 4})
|
||||||
|
list1 := NewList([]int{1, 2, 3, 4})
|
||||||
|
list2 := NewList([]int{1, 2, 3, 4})
|
||||||
|
|
||||||
|
del := NewList([]int{1})
|
||||||
|
del1 := NewList([]int{2, 3})
|
||||||
|
del2 := NewList([]int{1, 2, 5})
|
||||||
|
|
||||||
|
list.DeleteAll(del)
|
||||||
|
list1.DeleteAll(del1)
|
||||||
|
list2.DeleteAll(del2)
|
||||||
|
|
||||||
|
fmt.Println(list.Data()) //2,3,4
|
||||||
|
fmt.Println(list1.Data()) //1,4
|
||||||
|
fmt.Println(list2.Data()) //3,4
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="ForEach">ForEach</span>
|
||||||
|
<p>Performs the given action for each element of the list.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) ForEach(consumer func(T))
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
list := NewList([]int{1, 2, 3, 4})
|
||||||
|
|
||||||
|
result := make([]int, 0)
|
||||||
|
list.ForEach(func(i int) {
|
||||||
|
result = append(result, i)
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println(result.Data()) //1,2,3,4
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Iterator">Iterator</span>
|
||||||
|
<p>Returns an iterator over the elements in this list in proper sequence.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) Iterator() iterator.Iterator[T]
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
list := NewList([]int{1, 2, 3, 4})
|
||||||
|
|
||||||
|
iterator := list.Iterator()
|
||||||
|
|
||||||
|
result := make([]int, 0)
|
||||||
|
for iterator.HasNext() {
|
||||||
|
item, _ := iterator.Next()
|
||||||
|
result = append(result, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(result.Data()) //1,2,3,4
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="ListToMap">ListToMap</span>
|
||||||
|
<p>Converts a list to a map based on iteratee function.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ListToMap[T any, K comparable, V any](list *List[T], iteratee func(T) (K, V)) map[K]V
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
list := NewList([]int{1, 2, 3, 4})
|
||||||
|
|
||||||
|
result := ListToMap(list, func(n int) (int, bool) {
|
||||||
|
return n, n > 1
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println(result) //map[int]bool{1: false, 2: true, 3: true, 4: true}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="SubList">SubList</span>
|
### <span id="SubList">SubList</span>
|
||||||
<p>SubList returns a sub list of the original list between the specified fromIndex, inclusive, and toIndex, exclusive.</p>
|
<p>SubList returns a sub list of the original list between the specified fromIndex, inclusive, and toIndex, exclusive.</p>
|
||||||
@@ -876,9 +1110,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
l := list.NewList([]int{1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1})
|
l := list.NewList([]int{1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1})
|
||||||
|
|
||||||
fmt.Println(l.DeleteIf(func(a int) bool { return a == 1 })) // 12
|
fmt.Println(l.DeleteIf(func(a int) bool { return a == 1 })) // 12
|
||||||
fmt.Println(l.Data()) // []int{2, 3, 4}
|
fmt.Println(l.Data()) // []int{2, 3, 4}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import (
|
|||||||
- [PopLast](#PopLast)
|
- [PopLast](#PopLast)
|
||||||
- [DeleteAt](#DeleteAt)
|
- [DeleteAt](#DeleteAt)
|
||||||
- [InsertAt](#InsertAt)
|
- [InsertAt](#InsertAt)
|
||||||
|
|
||||||
- [UpdateAt](#UpdateAt)
|
- [UpdateAt](#UpdateAt)
|
||||||
- [Equal](#Equal)
|
- [Equal](#Equal)
|
||||||
- [IsEmpty](#IsEmpty)
|
- [IsEmpty](#IsEmpty)
|
||||||
@@ -48,6 +47,13 @@ import (
|
|||||||
- [Unique](#Unique)
|
- [Unique](#Unique)
|
||||||
- [Union](#Union)
|
- [Union](#Union)
|
||||||
- [Intersection](#Intersection)
|
- [Intersection](#Intersection)
|
||||||
|
- [Difference](#Difference)
|
||||||
|
- [SymmetricDifference](#SymmetricDifference)
|
||||||
|
- [RetainAll](#RetainAll)
|
||||||
|
- [DeleteAll](#DeleteAll)
|
||||||
|
- [ForEach](#ForEach)
|
||||||
|
- [Iterator](#Iterator)
|
||||||
|
- [ListToMap](#ListToMap)
|
||||||
- [SubList](#SubList)
|
- [SubList](#SubList)
|
||||||
- [DeleteIf](#DeleteIf)
|
- [DeleteIf](#DeleteIf)
|
||||||
|
|
||||||
@@ -62,11 +68,11 @@ import (
|
|||||||
|
|
||||||
```go
|
```go
|
||||||
type List[T any] struct {
|
type List[T any] struct {
|
||||||
data []T
|
data []T
|
||||||
}
|
}
|
||||||
func NewList[T any](data []T) *List[T]
|
func NewList[T any](data []T) *List[T]
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -92,7 +98,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) Contain(value T) bool
|
func (l *List[T]) Contain(value T) bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -121,7 +127,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) Data() []T
|
func (l *List[T]) Data() []T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -150,7 +156,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) ValueOf(index int) (*T, bool)
|
func (l *List[T]) ValueOf(index int) (*T, bool)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -180,7 +186,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) IndexOf(value T) int
|
func (l *List[T]) IndexOf(value T) int
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -207,7 +213,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) LastIndexOf(value T) int
|
func (l *List[T]) LastIndexOf(value T) int
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -233,7 +239,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) IndexOfFunc(f func(T) bool) int
|
func (l *List[T]) IndexOfFunc(f func(T) bool) int
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -259,7 +265,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) LastIndexOfFunc(f func(T) bool) int
|
func (l *List[T]) LastIndexOfFunc(f func(T) bool) int
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -287,7 +293,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) Push(value T)
|
func (l *List[T]) Push(value T)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -316,7 +322,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) PopFirst() (*T, bool)
|
func (l *List[T]) PopFirst() (*T, bool)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -348,7 +354,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) PopLast() (*T, bool)
|
func (l *List[T]) PopLast() (*T, bool)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -379,7 +385,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) DeleteAt(index int)
|
func (l *List[T]) DeleteAt(index int)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -417,7 +423,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) InsertAt(index int, value T)
|
func (l *List[T]) InsertAt(index int, value T)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -454,7 +460,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) UpdateAt(index int, value T)
|
func (l *List[T]) UpdateAt(index int, value T)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -487,7 +493,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) Equal(other *List[T]) bool
|
func (l *List[T]) Equal(other *List[T]) bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -517,7 +523,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) IsEmpty() bool
|
func (l *List[T]) IsEmpty() bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -547,7 +553,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) Clear()
|
func (l *List[T]) Clear()
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -575,7 +581,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) Clone() *List[T]
|
func (l *List[T]) Clone() *List[T]
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -604,7 +610,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) Merge(other *List[T]) *List[T]
|
func (l *List[T]) Merge(other *List[T]) *List[T]
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -633,7 +639,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) Size() int
|
func (l *List[T]) Size() int
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -660,7 +666,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) Cap() int
|
func (l *List[T]) Cap() int
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -671,7 +677,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := make([]int, 0, 100)
|
data := make([]int, 0, 100)
|
||||||
|
|
||||||
li := list.NewList(data)
|
li := list.NewList(data)
|
||||||
|
|
||||||
@@ -689,7 +695,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) Swap(i, j int)
|
func (l *List[T]) Swap(i, j int)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -718,7 +724,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) Reverse()
|
func (l *List[T]) Reverse()
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -747,7 +753,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) Unique()
|
func (l *List[T]) Unique()
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -776,7 +782,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) Union(other *List[T]) *List[T]
|
func (l *List[T]) Union(other *List[T]) *List[T]
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -806,7 +812,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) Intersection(other *List[T]) *List[T]
|
func (l *List[T]) Intersection(other *List[T]) *List[T]
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -826,16 +832,244 @@ func main() {
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Difference">Difference</span>
|
||||||
|
<p>差集运算。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) Difference(other *List[T]) *List[T]
|
||||||
|
```
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
list1 := NewList([]int{1, 2, 3})
|
||||||
|
list2 := NewList([]int{1, 2, 4})
|
||||||
|
|
||||||
|
list3 := list1.Intersection(list2)
|
||||||
|
|
||||||
|
fmt.Println(list3.Data()) //3
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="SymmetricDifference">SymmetricDifference</span>
|
||||||
|
<p>对称差集运算。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) SymmetricDifference(other *List[T]) *List[T]
|
||||||
|
```
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
list1 := NewList([]int{1, 2, 3})
|
||||||
|
list2 := NewList([]int{1, 2, 4})
|
||||||
|
|
||||||
|
list3 := list1.Intersection(list2)
|
||||||
|
|
||||||
|
fmt.Println(list3.Data()) //3, 4
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="RetainAll">RetainAll</span>
|
||||||
|
<p>仅保留列表中包含在给定列表中的元素。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) RetainAll(list *List[T]) bool
|
||||||
|
```
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
list := NewList([]int{1, 2, 3, 4})
|
||||||
|
list1 := NewList([]int{1, 2, 3, 4})
|
||||||
|
list2 := NewList([]int{1, 2, 3, 4})
|
||||||
|
|
||||||
|
retain := NewList([]int{1, 2})
|
||||||
|
retain1 := NewList([]int{2, 3})
|
||||||
|
retain2 := NewList([]int{1, 2, 5})
|
||||||
|
|
||||||
|
list.RetainAll(retain)
|
||||||
|
list1.RetainAll(retain1)
|
||||||
|
list2.RetainAll(retain2)
|
||||||
|
|
||||||
|
fmt.Println(list.Data()) //1, 2
|
||||||
|
fmt.Println(list1.Data()) //2, 3
|
||||||
|
fmt.Println(list2.Data()) //1, 2
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="DeleteAll">DeleteAll</span>
|
||||||
|
<p>从列表中删除给定列表中包含的所有元素。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) DeleteAll(list *List[T]) bool
|
||||||
|
```
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
list := NewList([]int{1, 2, 3, 4})
|
||||||
|
list1 := NewList([]int{1, 2, 3, 4})
|
||||||
|
list2 := NewList([]int{1, 2, 3, 4})
|
||||||
|
|
||||||
|
del := NewList([]int{1})
|
||||||
|
del1 := NewList([]int{2, 3})
|
||||||
|
del2 := NewList([]int{1, 2, 5})
|
||||||
|
|
||||||
|
list.DeleteAll(del)
|
||||||
|
list1.DeleteAll(del1)
|
||||||
|
list2.DeleteAll(del2)
|
||||||
|
|
||||||
|
fmt.Println(list.Data()) //2,3,4
|
||||||
|
fmt.Println(list1.Data()) //1,4
|
||||||
|
fmt.Println(list2.Data()) //3,4
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="ForEach">ForEach</span>
|
||||||
|
<p>对列表的每个元素执行给定的操作。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) ForEach(consumer func(T))
|
||||||
|
```
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
list := NewList([]int{1, 2, 3, 4})
|
||||||
|
|
||||||
|
result := make([]int, 0)
|
||||||
|
list.ForEach(func(i int) {
|
||||||
|
result = append(result, i)
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println(result.Data()) //1,2,3,4
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Iterator">Iterator</span>
|
||||||
|
<p>按顺序返回列表中元素的迭代器。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *List[T]) Iterator() iterator.Iterator[T]
|
||||||
|
```
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
list := NewList([]int{1, 2, 3, 4})
|
||||||
|
|
||||||
|
iterator := list.Iterator()
|
||||||
|
|
||||||
|
result := make([]int, 0)
|
||||||
|
for iterator.HasNext() {
|
||||||
|
item, _ := iterator.Next()
|
||||||
|
result = append(result, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(result.Data()) //1,2,3,4
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="ListToMap">ListToMap</span>
|
||||||
|
<p>基于iteratee函数将列表转换为映射map。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ListToMap[T any, K comparable, V any](list *List[T], iteratee func(T) (K, V)) map[K]V
|
||||||
|
```
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
list := NewList([]int{1, 2, 3, 4})
|
||||||
|
|
||||||
|
result := ListToMap(list, func(n int) (int, bool) {
|
||||||
|
return n, n > 1
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println(result) //map[int]bool{1: false, 2: true, 3: true, 4: true}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="SubList">SubList</span>
|
### <span id="SubList">SubList</span>
|
||||||
<p>SubList returns a sub list of the original list between the specified fromIndex, inclusive, and toIndex, exclusive.</p>
|
<p>返回指定的fromIndex(包含)和toIndex(不包含)之间的原始列表的子列表。</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func (l *List[T]) SubList(fromIndex, toIndex int) *List[T]
|
func (l *List[T]) SubList(fromIndex, toIndex int) *List[T]
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -863,7 +1097,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (l *List[T]) DeleteIf(f func(T) bool) int
|
func (l *List[T]) DeleteIf(f func(T) bool) int
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -874,9 +1108,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
l := list.NewList([]int{1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1})
|
l := list.NewList([]int{1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1})
|
||||||
|
|
||||||
fmt.Println(l.DeleteIf(func(a int) bool { return a == 1 })) // 12
|
fmt.Println(l.DeleteIf(func(a int) bool { return a == 1 })) // 12
|
||||||
fmt.Println(l.Data()) // []int{2, 3, 4}
|
fmt.Println(l.Data()) // []int{2, 3, 4}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -99,7 +99,7 @@ type ArrayQueue[T any] struct {
|
|||||||
size int
|
size int
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -125,7 +125,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *ArrayQueue[T]) Data() []T
|
func (q *ArrayQueue[T]) Data() []T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -152,7 +152,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *ArrayQueue[T]) Enqueue(item T) bool
|
func (q *ArrayQueue[T]) Enqueue(item T) bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -183,7 +183,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *ArrayQueue[T]) Dequeue() (T, bool)
|
func (q *ArrayQueue[T]) Dequeue() (T, bool)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -215,7 +215,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *ArrayQueue[T]) Front() T
|
func (q *ArrayQueue[T]) Front() T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -247,7 +247,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *ArrayQueue[T]) Back() T
|
func (q *ArrayQueue[T]) Back() T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -278,7 +278,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *ArrayQueue[T]) Size() int
|
func (q *ArrayQueue[T]) Size() int
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -308,7 +308,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *ArrayQueue[T]) IsEmpty() bool
|
func (q *ArrayQueue[T]) IsEmpty() bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -341,7 +341,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *ArrayQueue[T]) IsFull() bool
|
func (q *ArrayQueue[T]) IsFull() bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -373,7 +373,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *ArrayQueue[T]) Clear()
|
func (q *ArrayQueue[T]) Clear()
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -404,7 +404,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *ArrayQueue[T]) Contain(value T) bool
|
func (q *ArrayQueue[T]) Contain(value T) bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -448,7 +448,7 @@ type QueueNode[T any] struct {
|
|||||||
Next *QueueNode[T]
|
Next *QueueNode[T]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -474,7 +474,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *LinkedQueue[T]) Data() []T
|
func (q *LinkedQueue[T]) Data() []T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -501,7 +501,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *LinkedQueue[T]) Enqueue(value T)
|
func (q *LinkedQueue[T]) Enqueue(value T)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -532,7 +532,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *LinkedQueue[T]) Dequeue() (T, error)
|
func (q *LinkedQueue[T]) Dequeue() (T, error)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -564,7 +564,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *LinkedQueue[T]) Front() (*T, error)
|
func (q *LinkedQueue[T]) Front() (*T, error)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -596,7 +596,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *LinkedQueue[T]) Back() (*T, error)
|
func (q *LinkedQueue[T]) Back() (*T, error)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -627,7 +627,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *LinkedQueue[T]) Size() int
|
func (q *LinkedQueue[T]) Size() int
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -657,7 +657,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *LinkedQueue[T]) IsEmpty() bool
|
func (q *LinkedQueue[T]) IsEmpty() bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -690,7 +690,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *LinkedQueue[T]) Clear()
|
func (q *LinkedQueue[T]) Clear()
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -721,7 +721,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *LinkedQueue[T]) Contain(value T) bool
|
func (q *LinkedQueue[T]) Contain(value T) bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -763,7 +763,7 @@ type CircularQueue[T any] struct {
|
|||||||
capacity int
|
capacity int
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -789,7 +789,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *CircularQueue[T]) Data() []T
|
func (q *CircularQueue[T]) Data() []T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -816,7 +816,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *CircularQueue[T]) Enqueue(value T) error
|
func (q *CircularQueue[T]) Enqueue(value T) error
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -847,7 +847,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *CircularQueue[T]) Dequeue() (*T, bool)
|
func (q *CircularQueue[T]) Dequeue() (*T, bool)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -880,7 +880,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *CircularQueue[T]) Front() T
|
func (q *CircularQueue[T]) Front() T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -912,7 +912,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *CircularQueue[T]) Back() T
|
func (q *CircularQueue[T]) Back() T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -943,7 +943,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *CircularQueue[T]) Size() int
|
func (q *CircularQueue[T]) Size() int
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -973,7 +973,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *CircularQueue[T]) IsEmpty() bool
|
func (q *CircularQueue[T]) IsEmpty() bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -1006,7 +1006,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *CircularQueue[T]) IsFull() bool
|
func (q *CircularQueue[T]) IsFull() bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -1038,7 +1038,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *CircularQueue[T]) Clear()
|
func (q *CircularQueue[T]) Clear()
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -1069,7 +1069,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *CircularQueue[T]) Contain(value T) bool
|
func (q *CircularQueue[T]) Contain(value T) bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -1108,7 +1108,7 @@ type PriorityQueue[T any] struct {
|
|||||||
comparator lancetconstraints.Comparator
|
comparator lancetconstraints.Comparator
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -1134,7 +1134,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *PriorityQueue[T]) Data() []T
|
func (q *PriorityQueue[T]) Data() []T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -1161,7 +1161,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *PriorityQueue[T]) Enqueue(item T) bool
|
func (q *PriorityQueue[T]) Enqueue(item T) bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -1207,7 +1207,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *PriorityQueue[T]) Dequeue() (T, bool)
|
func (q *PriorityQueue[T]) Dequeue() (T, bool)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -1254,7 +1254,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *PriorityQueue[T]) IsEmpty() bool
|
func (q *PriorityQueue[T]) IsEmpty() bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -1301,7 +1301,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *PriorityQueue[T]) IsFull() bool
|
func (q *PriorityQueue[T]) IsFull() bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -1348,7 +1348,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (q *PriorityQueue[T]) Size() int
|
func (q *PriorityQueue[T]) Size() int
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ import (
|
|||||||
type Set[T comparable] map[T]bool
|
type Set[T comparable] map[T]bool
|
||||||
func NewSet[T comparable](items ...T) Set[T]
|
func NewSet[T comparable](items ...T) Set[T]
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -81,7 +81,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func NewSetFromSlice[T comparable](items []T) Set[T]
|
func NewSetFromSlice[T comparable](items []T) Set[T]
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -107,7 +107,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s Set[T]) Values() []T
|
func (s Set[T]) Values() []T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -134,7 +134,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s Set[T]) Add(items ...T)
|
func (s Set[T]) Add(items ...T)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -161,7 +161,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s Set[T]) AddIfNotExist(item T) bool
|
func (s Set[T]) AddIfNotExist(item T) bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -193,7 +193,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s Set[T]) AddIfNotExistBy(item T, checker func(element T) bool) bool
|
func (s Set[T]) AddIfNotExistBy(item T, checker func(element T) bool) bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -232,7 +232,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s Set[T]) Delete(items ...T)
|
func (s Set[T]) Delete(items ...T)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -261,7 +261,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s Set[T]) Contain(item T) bool
|
func (s Set[T]) Contain(item T) bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -291,7 +291,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s Set[T]) ContainAll(other Set[T]) bool
|
func (s Set[T]) ContainAll(other Set[T]) bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -321,7 +321,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s Set[T]) Size() int
|
func (s Set[T]) Size() int
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -348,7 +348,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s Set[T]) Clone() Set[T]
|
func (s Set[T]) Clone() Set[T]
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -378,7 +378,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s Set[T]) Equal(other Set[T]) bool
|
func (s Set[T]) Equal(other Set[T]) bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -408,7 +408,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s Set[T]) Iterate(fn func(item T))
|
func (s Set[T]) Iterate(fn func(item T))
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -439,7 +439,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s Set[T]) IsEmpty() bool
|
func (s Set[T]) IsEmpty() bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -468,7 +468,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s Set[T]) Union(other Set[T]) Set[T]
|
func (s Set[T]) Union(other Set[T]) Set[T]
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -497,7 +497,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s Set[T]) Intersection(other Set[T]) Set[T]
|
func (s Set[T]) Intersection(other Set[T]) Set[T]
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -525,7 +525,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s Set[T]) SymmetricDifference(other Set[T]) Set[T]
|
func (s Set[T]) SymmetricDifference(other Set[T]) Set[T]
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -556,7 +556,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s Set[T]) Minus(comparedSet Set[T]) Set[T]
|
func (s Set[T]) Minus(comparedSet Set[T]) Set[T]
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ type ArrayStack[T any] struct {
|
|||||||
}
|
}
|
||||||
func NewArrayStack[T any]() *ArrayStack[T]
|
func NewArrayStack[T any]() *ArrayStack[T]
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -91,7 +91,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s *ArrayStack[T]) Push(value T)
|
func (s *ArrayStack[T]) Push(value T)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -122,7 +122,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s *ArrayStack[T]) Pop() (*T, error)
|
func (s *ArrayStack[T]) Pop() (*T, error)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -157,7 +157,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s *ArrayStack[T]) Peak() (*T, error)
|
func (s *ArrayStack[T]) Peak() (*T, error)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -192,7 +192,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s *ArrayStack[T]) Data() []T
|
func (s *ArrayStack[T]) Data() []T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -223,7 +223,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s *ArrayStack[T]) Size() int
|
func (s *ArrayStack[T]) Size() int
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -254,7 +254,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s *ArrayStack[T]) IsEmpty() bool
|
func (s *ArrayStack[T]) IsEmpty() bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -287,7 +287,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s *ArrayStack[T]) Clear()
|
func (s *ArrayStack[T]) Clear()
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -331,7 +331,7 @@ type LinkedStack[T any] struct {
|
|||||||
}
|
}
|
||||||
func NewLinkedStack[T any]() *LinkedStack[T]
|
func NewLinkedStack[T any]() *LinkedStack[T]
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -358,7 +358,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s *LinkedStack[T]) Push(value T)
|
func (s *LinkedStack[T]) Push(value T)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -389,7 +389,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s *LinkedStack[T]) Pop() (*T, error)
|
func (s *LinkedStack[T]) Pop() (*T, error)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -424,7 +424,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s *LinkedStack[T]) Peak() (*T, error)
|
func (s *LinkedStack[T]) Peak() (*T, error)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -459,7 +459,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s *LinkedStack[T]) Data() []T
|
func (s *LinkedStack[T]) Data() []T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -490,7 +490,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s *LinkedStack[T]) Size() int
|
func (s *LinkedStack[T]) Size() int
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -521,7 +521,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s *LinkedStack[T]) IsEmpty() bool
|
func (s *LinkedStack[T]) IsEmpty() bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -554,7 +554,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s *LinkedStack[T]) Clear()
|
func (s *LinkedStack[T]) Clear()
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -588,7 +588,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (s *LinkedStack[T]) Print()
|
func (s *LinkedStack[T]) Print()
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ type TreeNode[T any] struct {
|
|||||||
Right *TreeNode[T]
|
Right *TreeNode[T]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -103,7 +103,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (t *BSTree[T]) Insert(data T)
|
func (t *BSTree[T]) Insert(data T)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -149,7 +149,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (t *BSTree[T]) Delete(data T)
|
func (t *BSTree[T]) Delete(data T)
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -197,7 +197,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (t *BSTree[T]) PreOrderTraverse() []T
|
func (t *BSTree[T]) PreOrderTraverse() []T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -243,7 +243,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (t *BSTree[T]) InOrderTraverse() []T
|
func (t *BSTree[T]) InOrderTraverse() []T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -289,7 +289,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (t *BSTree[T]) PostOrderTraverse() []T
|
func (t *BSTree[T]) PostOrderTraverse() []T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -335,7 +335,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (t *BSTree[T]) LevelOrderTraverse() []T
|
func (t *BSTree[T]) LevelOrderTraverse() []T
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -381,7 +381,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (t *BSTree[T]) Depth() int
|
func (t *BSTree[T]) Depth() int
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -427,7 +427,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (t *BSTree[T]) HasSubTree(subTree *BSTree[T]) bool
|
func (t *BSTree[T]) HasSubTree(subTree *BSTree[T]) bool
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -479,7 +479,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func (t *BSTree[T]) Print()
|
func (t *BSTree[T]) Print()
|
||||||
```
|
```
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ import (
|
|||||||
func ClearFile(path string) error
|
func ClearFile(path string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -80,7 +80,7 @@ func main() {
|
|||||||
func CreateFile(path string) bool
|
func CreateFile(path string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -132,7 +132,7 @@ func main() {
|
|||||||
func CopyFile(srcFilePath string, dstFilePath string) error
|
func CopyFile(srcFilePath string, dstFilePath string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -160,7 +160,7 @@ func main() {
|
|||||||
func FileMode(path string) (fs.FileMode, error)
|
func FileMode(path string) (fs.FileMode, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -189,7 +189,7 @@ func main() {
|
|||||||
func MiMeType(file any) string
|
func MiMeType(file any) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -220,7 +220,7 @@ func main() {
|
|||||||
func IsExist(path string) bool
|
func IsExist(path string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -247,7 +247,7 @@ func main() {
|
|||||||
func IsLink(path string) bool
|
func IsLink(path string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -273,7 +273,7 @@ func main() {
|
|||||||
func IsDir(path string) bool
|
func IsDir(path string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -302,7 +302,7 @@ func main() {
|
|||||||
func ListFileNames(path string) ([]string, error)
|
func ListFileNames(path string) ([]string, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -328,7 +328,7 @@ func main() {
|
|||||||
func RemoveFile(path string) error
|
func RemoveFile(path string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -356,7 +356,7 @@ func main() {
|
|||||||
func ReadFileToString(path string) (string, error)
|
func ReadFileToString(path string) (string, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -389,7 +389,7 @@ func main() {
|
|||||||
func ReadFileByLine(path string)([]string, error)
|
func ReadFileByLine(path string)([]string, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -423,7 +423,7 @@ func main() {
|
|||||||
func Zip(fpath string, destPath string) error
|
func Zip(fpath string, destPath string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -451,7 +451,7 @@ func main() {
|
|||||||
func UnZip(zipFile string, destPath string) error
|
func UnZip(zipFile string, destPath string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ import (
|
|||||||
func Comma[T constraints.Float | constraints.Integer | string](value T, symbol string) string
|
func Comma[T constraints.Float | constraints.Integer | string](value T, symbol string) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ import (
|
|||||||
func After(n int, fn any) func(args ...any) []reflect.Value
|
func After(n int, fn any) func(args ...any) []reflect.Value
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -79,7 +79,7 @@ func main() {
|
|||||||
func Before(n int, fn any) func(args ...any) []reflect.Value
|
func Before(n int, fn any) func(args ...any) []reflect.Value
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -117,7 +117,7 @@ type CurryFn[T any] func(...T) T
|
|||||||
func (cf CurryFn[T]) New(val T) func(...T) T
|
func (cf CurryFn[T]) New(val T) func(...T) T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -156,7 +156,7 @@ func main() {
|
|||||||
func Compose[T any](fnList ...func(...T) T) func(...T) T
|
func Compose[T any](fnList ...func(...T) T) func(...T) T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -194,7 +194,7 @@ func main() {
|
|||||||
func Debounced(fn func(), duration time.Duration) func()
|
func Debounced(fn func(), duration time.Duration) func()
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -244,7 +244,7 @@ func main() {
|
|||||||
func Delay(delay time.Duration, fn any, args ...any)
|
func Delay(delay time.Duration, fn any, args ...any)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -276,7 +276,7 @@ func main() {
|
|||||||
func Schedule(d time.Duration, fn any, args ...any) chan bool
|
func Schedule(d time.Duration, fn any, args ...any) chan bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -315,7 +315,7 @@ func main() {
|
|||||||
func Pipeline[T any](funcs ...func(T) T) func(T) T
|
func Pipeline[T any](funcs ...func(T) T) func(T) T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -366,7 +366,7 @@ func (w *Watcher) Reset() //reset the watcher
|
|||||||
func (w *Watcher) GetElapsedTime() time.Duration //get the elapsed time of function execution
|
func (w *Watcher) GetElapsedTime() time.Duration //get the elapsed time of function execution
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ import (
|
|||||||
func ForEach[K comparable, V any](m map[K]V, iteratee func(key K, value V))
|
func ForEach[K comparable, V any](m map[K]V, iteratee func(key K, value V))
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -86,7 +86,7 @@ func main() {
|
|||||||
func Filter[K comparable, V any](m map[K]V, predicate func(key K, value V) bool) map[K]V
|
func Filter[K comparable, V any](m map[K]V, predicate func(key K, value V) bool) map[K]V
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -131,7 +131,7 @@ func main() {
|
|||||||
func Intersect[K comparable, V any](maps ...map[K]V) map[K]V
|
func Intersect[K comparable, V any](maps ...map[K]V) map[K]V
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -186,7 +186,7 @@ func main() {
|
|||||||
func Keys[K comparable, V any](m map[K]V) []K
|
func Keys[K comparable, V any](m map[K]V) []K
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -225,7 +225,7 @@ func main() {
|
|||||||
func Merge[K comparable, V any](maps ...map[K]V) map[K]V
|
func Merge[K comparable, V any](maps ...map[K]V) map[K]V
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -264,7 +264,7 @@ func main() {
|
|||||||
func Minus[K comparable, V any](mapA, mapB map[K]V) map[K]V
|
func Minus[K comparable, V any](mapA, mapB map[K]V) map[K]V
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -306,7 +306,7 @@ func main() {
|
|||||||
func Values[K comparable, V any](m map[K]V) []V
|
func Values[K comparable, V any](m map[K]V) []V
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -343,7 +343,7 @@ func main() {
|
|||||||
func IsDisjoint[K comparable, V any](mapA, mapB map[K]V) bool
|
func IsDisjoint[K comparable, V any](mapA, mapB map[K]V) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ import (
|
|||||||
func Average[T constraints.Integer | constraints.Float](numbers ...T) T
|
func Average[T constraints.Integer | constraints.Float](numbers ...T) T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -84,7 +84,7 @@ func main() {
|
|||||||
func Exponent(x, n int64) int64
|
func Exponent(x, n int64) int64
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -120,7 +120,7 @@ func main() {
|
|||||||
func Fibonacci(first, second, n int) int
|
func Fibonacci(first, second, n int) int
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -156,7 +156,7 @@ func main() {
|
|||||||
func Factorial(x uint) uint
|
func Factorial(x uint) uint
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -192,7 +192,7 @@ func main() {
|
|||||||
func Max[T constraints.Integer | constraints.Float](numbers ...T) T
|
func Max[T constraints.Integer | constraints.Float](numbers ...T) T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -225,7 +225,7 @@ func main() {
|
|||||||
func MaxBy[T any](slice []T, comparator func(T, T) bool) T
|
func MaxBy[T any](slice []T, comparator func(T, T) bool) T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -269,7 +269,7 @@ func main() {
|
|||||||
func Min[T constraints.Integer | constraints.Float](numbers ...T) T
|
func Min[T constraints.Integer | constraints.Float](numbers ...T) T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -302,7 +302,7 @@ func main() {
|
|||||||
func MinBy[T any](slice []T, comparator func(T, T) bool) T
|
func MinBy[T any](slice []T, comparator func(T, T) bool) T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -346,7 +346,7 @@ func main() {
|
|||||||
func Percent(val, total float64, n int) float64
|
func Percent(val, total float64, n int) float64
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -379,7 +379,7 @@ func main() {
|
|||||||
func RoundToFloat(x float64, n int) float64
|
func RoundToFloat(x float64, n int) float64
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -415,7 +415,7 @@ func main() {
|
|||||||
func RoundToString(x float64, n int) string
|
func RoundToString(x float64, n int) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -451,7 +451,7 @@ func main() {
|
|||||||
func TruncRound(x float64, n int) float64
|
func TruncRound(x float64, n int) float64
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ import (
|
|||||||
func ConvertMapToQueryString(param map[string]any) string
|
func ConvertMapToQueryString(param map[string]any) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -94,7 +94,7 @@ func main() {
|
|||||||
func EncodeUrl(urlStr string) (string, error)
|
func EncodeUrl(urlStr string) (string, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -129,7 +129,7 @@ func main() {
|
|||||||
func GetInternalIp() string
|
func GetInternalIp() string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -161,7 +161,7 @@ func main() {
|
|||||||
func GetIps() []string
|
func GetIps() []string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -191,7 +191,7 @@ func main() {
|
|||||||
func GetMacAddrs() []string {
|
func GetMacAddrs() []string {
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -235,7 +235,7 @@ type PublicIpInfo struct {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -265,7 +265,7 @@ func main() {
|
|||||||
func GetRequestPublicIp(req *http.Request) string
|
func GetRequestPublicIp(req *http.Request) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -303,7 +303,7 @@ func main() {
|
|||||||
func IsPublicIP(IP net.IP) bool
|
func IsPublicIP(IP net.IP) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -340,7 +340,7 @@ func main() {
|
|||||||
func IsInternalIP(IP net.IP) bool
|
func IsInternalIP(IP net.IP) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -384,7 +384,7 @@ type HttpRequest struct {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -441,7 +441,7 @@ func NewHttpClientWithConfig(config *HttpClientConfig) *HttpClient
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -472,7 +472,7 @@ func main() {
|
|||||||
func (client *HttpClient) SendRequest(request *HttpRequest) (*http.Response, error)
|
func (client *HttpClient) SendRequest(request *HttpRequest) (*http.Response, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -526,7 +526,7 @@ func main() {
|
|||||||
func (client *HttpClient) DecodeResponse(resp *http.Response, target any) error
|
func (client *HttpClient) DecodeResponse(resp *http.Response, target any) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -580,7 +580,7 @@ func main() {
|
|||||||
func StructToUrlValues(targetStruct any) url.Values
|
func StructToUrlValues(targetStruct any) url.Values
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -624,7 +624,7 @@ func main() {
|
|||||||
func HttpGet(url string, params ...any) (*http.Response, error)
|
func HttpGet(url string, params ...any) (*http.Response, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -666,7 +666,7 @@ func main() {
|
|||||||
func HttpPost(url string, params ...any) (*http.Response, error)
|
func HttpPost(url string, params ...any) (*http.Response, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -715,7 +715,7 @@ func main() {
|
|||||||
func HttpPut(url string, params ...any) (*http.Response, error)
|
func HttpPut(url string, params ...any) (*http.Response, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -765,7 +765,7 @@ func main() {
|
|||||||
func HttpDelete(url string, params ...any) (*http.Response, error)
|
func HttpDelete(url string, params ...any) (*http.Response, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -804,7 +804,7 @@ func main() {
|
|||||||
func HttpPatch(url string, params ...any) (*http.Response, error)
|
func HttpPatch(url string, params ...any) (*http.Response, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -850,7 +850,7 @@ func main() {
|
|||||||
func ParseHttpResponse(resp *http.Response, obj any) error
|
func ParseHttpResponse(resp *http.Response, obj any) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ import (
|
|||||||
func RandBytes(length int) []byte
|
func RandBytes(length int) []byte
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -71,7 +71,7 @@ func main() {
|
|||||||
func RandInt(min, max int) int
|
func RandInt(min, max int) int
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -97,7 +97,7 @@ func main() {
|
|||||||
func RandString(length int) string
|
func RandString(length int) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -123,7 +123,7 @@ func main() {
|
|||||||
func RandUpper(length int) string
|
func RandUpper(length int) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -149,7 +149,7 @@ func main() {
|
|||||||
func RandLower(length int) string
|
func RandLower(length int) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -175,7 +175,7 @@ func main() {
|
|||||||
func RandNumeral(length int) string
|
func RandNumeral(length int) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -201,7 +201,7 @@ func main() {
|
|||||||
func RandNumeralOrLetter(length int) string
|
func RandNumeralOrLetter(length int) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -227,7 +227,7 @@ func main() {
|
|||||||
func UUIdV4() (string, error)
|
func UUIdV4() (string, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ import (
|
|||||||
func Context(ctx context.Context)
|
func Context(ctx context.Context)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -89,7 +89,7 @@ func main() {
|
|||||||
type RetryFunc func() error
|
type RetryFunc func() error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -135,7 +135,7 @@ func main() {
|
|||||||
func RetryTimes(n uint)
|
func RetryTimes(n uint)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -178,7 +178,7 @@ func main() {
|
|||||||
func RetryDuration(d time.Duration)
|
func RetryDuration(d time.Duration)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -224,7 +224,7 @@ func main() {
|
|||||||
func Retry(retryFunc RetryFunc, opts ...Option) error
|
func Retry(retryFunc RetryFunc, opts ...Option) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|||||||
294
docs/slice.md
294
docs/slice.md
@@ -35,6 +35,9 @@ import (
|
|||||||
- [DifferenceWith](#DifferenceWith)
|
- [DifferenceWith](#DifferenceWith)
|
||||||
- [DeleteAt](#DeleteAt)
|
- [DeleteAt](#DeleteAt)
|
||||||
- [Drop](#Drop)
|
- [Drop](#Drop)
|
||||||
|
- [DropRight](#DropRight)
|
||||||
|
- [DropWhile](#DropWhile)
|
||||||
|
- [DropRightWhile](#DropRightWhile)
|
||||||
- [Equal](#Equal)
|
- [Equal](#Equal)
|
||||||
- [EqualWith](#EqualWith)
|
- [EqualWith](#EqualWith)
|
||||||
- [Every](#Every)
|
- [Every](#Every)
|
||||||
@@ -60,6 +63,10 @@ import (
|
|||||||
- [ReplaceAll](#ReplaceAll)
|
- [ReplaceAll](#ReplaceAll)
|
||||||
- [Repeat](#Repeat)
|
- [Repeat](#Repeat)
|
||||||
- [Shuffle](#Shuffle)
|
- [Shuffle](#Shuffle)
|
||||||
|
- [IsAscending](#IsAscending)
|
||||||
|
- [IsDescending](#IsDescending)
|
||||||
|
- [IsSorted](#IsSorted)
|
||||||
|
- [IsSortedByKey](#IsSortedByKey)
|
||||||
- [Sort](#Sort)
|
- [Sort](#Sort)
|
||||||
- [SortBy](#SortBy)
|
- [SortBy](#SortBy)
|
||||||
- [SortByField<sup>deprecated</sup>](#SortByField)
|
- [SortByField<sup>deprecated</sup>](#SortByField)
|
||||||
@@ -487,7 +494,7 @@ func main() {
|
|||||||
|
|
||||||
### <span id="Drop">Drop</span>
|
### <span id="Drop">Drop</span>
|
||||||
|
|
||||||
<p>Creates a slice with `n` elements dropped from the beginning when n > 0, or `n` elements dropped from the ending when n < 0.</p>
|
<p>Drop n elements from the start of a slice.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
@@ -505,20 +512,139 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
result1 := slice.Drop([]string{"a", "b", "c"}, 0)
|
result1 := slice.Drop([]string{"a", "b", "c"}, 0)
|
||||||
result2 := slice.Drop([]string{"a", "b", "c"}, 1)
|
result2 := slice.Drop([]string{"a", "b", "c"}, 1)
|
||||||
result3 := slice.Drop([]string{"a", "b", "c"}, -1)
|
result3 := slice.Drop([]string{"a", "b", "c"}, -1)
|
||||||
result4 := slice.Drop([]string{"a", "b", "c"}, 4)
|
result4 := slice.Drop([]string{"a", "b", "c"}, 4)
|
||||||
|
|
||||||
fmt.Println(result1)
|
fmt.Println(result1)
|
||||||
fmt.Println(result2)
|
fmt.Println(result2)
|
||||||
fmt.Println(result3)
|
fmt.Println(result3)
|
||||||
fmt.Println(result4)
|
fmt.Println(result4)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// [a b c]
|
// [a b c]
|
||||||
// [b c]
|
// [b c]
|
||||||
// [a b]
|
// [a b c]
|
||||||
// []
|
// []
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="DropRight">DropRight</span>
|
||||||
|
|
||||||
|
<p>Drop n elements from the end of a slice.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func DropRight[T any](slice []T, n int) []T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := slice.DropRight([]string{"a", "b", "c"}, 0)
|
||||||
|
result2 := slice.DropRight([]string{"a", "b", "c"}, 1)
|
||||||
|
result3 := slice.DropRight([]string{"a", "b", "c"}, -1)
|
||||||
|
result4 := slice.DropRight([]string{"a", "b", "c"}, 4)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [a b c]
|
||||||
|
// [a b]
|
||||||
|
// [a b c]
|
||||||
|
// []
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="DropWhile">DropWhile</span>
|
||||||
|
|
||||||
|
<p>Drop n elements from the start of a slice while predicate function returns true.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func DropWhile[T any](slice []T, predicate func(item T) bool) []T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := slice.DropWhile(numbers, func(n int) bool {
|
||||||
|
return n != 2
|
||||||
|
})
|
||||||
|
result2 := slice.DropWhile(numbers, func(n int) bool {
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
result3 := slice.DropWhile(numbers, func(n int) bool {
|
||||||
|
return n == 0
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [2 3 4 5]
|
||||||
|
// []
|
||||||
|
// [1 2 3 4 5]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="DropRightWhile">DropRightWhile</span>
|
||||||
|
|
||||||
|
<p>Drop n elements from the end of a slice while predicate function returns true.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func DropRightWhile[T any](slice []T, predicate func(item T) bool) []T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
numbers := []int{1, 2, 3, 4, 5}
|
||||||
|
|
||||||
|
result1 := slice.DropRightWhile(numbers, func(n int) bool {
|
||||||
|
return n != 2
|
||||||
|
})
|
||||||
|
result2 := slice.DropRightWhile(numbers, func(n int) bool {
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
result3 := slice.DropRightWhile(numbers, func(n int) bool {
|
||||||
|
return n == 0
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [1 2]
|
||||||
|
// []
|
||||||
|
// [1 2 3 4 5]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -1348,6 +1474,148 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="IsAscending">IsAscending</span>
|
||||||
|
|
||||||
|
<p>Checks if a slice is ascending order.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func IsAscending[T constraints.Ordered](slice []T) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := slice.IsAscending([]int{1, 2, 3, 4, 5})
|
||||||
|
result2 := slice.IsAscending([]int{5, 4, 3, 2, 1})
|
||||||
|
result3 := slice.IsAscending([]int{2, 1, 3, 4, 5})
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="IsDescending">IsDescending</span>
|
||||||
|
|
||||||
|
<p>Checks if a slice is descending order.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func IsDescending[T constraints.Ordered](slice []T) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := slice.IsDescending([]int{5, 4, 3, 2, 1})
|
||||||
|
result2 := slice.IsDescending([]int{1, 2, 3, 4, 5})
|
||||||
|
result3 := slice.IsDescending([]int{2, 1, 3, 4, 5})
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="IsSorted">IsSorted</span>
|
||||||
|
|
||||||
|
<p>Checks if a slice is sorted (ascending or descending).</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func IsSorted[T constraints.Ordered](slice []T) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := slice.IsSorted([]int{5, 4, 3, 2, 1})
|
||||||
|
result2 := slice.IsSorted([]int{1, 2, 3, 4, 5})
|
||||||
|
result3 := slice.IsSorted([]int{2, 1, 3, 4, 5})
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="IsSortedByKey">IsSortedByKey</span>
|
||||||
|
|
||||||
|
<p>Checks if a slice is sorted by iteratee function.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func IsSortedByKey[T any, K constraints.Ordered](slice []T, iteratee func(item T) K) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := slice.IsSortedByKey([]string{"a", "ab", "abc"}, func(s string) int {
|
||||||
|
return len(s)
|
||||||
|
})
|
||||||
|
result2 := slice.IsSortedByKey([]string{"abc", "ab", "a"}, func(s string) int {
|
||||||
|
return len(s)
|
||||||
|
})
|
||||||
|
result3 := slice.IsSortedByKey([]string{"abc", "a", "ab"}, func(s string) int {
|
||||||
|
return len(s)
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="Sort">Sort</span>
|
### <span id="Sort">Sort</span>
|
||||||
|
|
||||||
<p>Sorts a slice of any ordered type(number or string), use quick sort algrithm. Default sort order is ascending (asc), if want descending order, set param `sortOrder` to `desc`. Ordered type: number(all ints uints floats) or string.
|
<p>Sorts a slice of any ordered type(number or string), use quick sort algrithm. Default sort order is ascending (asc), if want descending order, set param `sortOrder` to `desc`. Ordered type: number(all ints uints floats) or string.
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ import (
|
|||||||
- [DifferenceWith](#DifferenceWith)
|
- [DifferenceWith](#DifferenceWith)
|
||||||
- [DeleteAt](#DeleteAt)
|
- [DeleteAt](#DeleteAt)
|
||||||
- [Drop](#Drop)
|
- [Drop](#Drop)
|
||||||
|
- [DropRight](#DropRight)
|
||||||
|
- [DropWhile](#DropWhile)
|
||||||
|
- [DropRightWhile](#DropRightWhile)
|
||||||
- [Every](#Every)
|
- [Every](#Every)
|
||||||
- [Equal](#Equal)
|
- [Equal](#Equal)
|
||||||
- [EqualWith](#EqualWith)
|
- [EqualWith](#EqualWith)
|
||||||
@@ -60,6 +63,10 @@ import (
|
|||||||
- [ReplaceAll](#ReplaceAll)
|
- [ReplaceAll](#ReplaceAll)
|
||||||
- [Repeat](#Repeat)
|
- [Repeat](#Repeat)
|
||||||
- [Shuffle](#Shuffle)
|
- [Shuffle](#Shuffle)
|
||||||
|
- [IsAscending](#IsAscending)
|
||||||
|
- [IsDescending](#IsDescending)
|
||||||
|
- [IsSorted](#IsSorted)
|
||||||
|
- [IsSortedByKey](#IsSortedByKey)
|
||||||
- [Sort](#Sort)
|
- [Sort](#Sort)
|
||||||
- [SortBy](#SortBy)
|
- [SortBy](#SortBy)
|
||||||
- [SortByField<sup>deprecated</sup>](#SortByField)
|
- [SortByField<sup>deprecated</sup>](#SortByField)
|
||||||
@@ -90,7 +97,7 @@ import (
|
|||||||
func AppendIfAbsent[T comparable](slice []T, item T) []T
|
func AppendIfAbsent[T comparable](slice []T, item T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -121,7 +128,7 @@ func main() {
|
|||||||
func Contain[T comparable](slice []T, target T) bool
|
func Contain[T comparable](slice []T, target T) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -152,7 +159,7 @@ func main() {
|
|||||||
func ContainSubSlice[T comparable](slice, subSlice []T) bool
|
func ContainSubSlice[T comparable](slice, subSlice []T) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -183,7 +190,7 @@ func main() {
|
|||||||
func Chunk[T any](slice []T, size int) [][]T
|
func Chunk[T any](slice []T, size int) [][]T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -225,7 +232,7 @@ func main() {
|
|||||||
func Compact[T comparable](slice []T) []T
|
func Compact[T comparable](slice []T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -262,7 +269,7 @@ func main() {
|
|||||||
func Concat[T any](slice []T, slices ...[]T) []T
|
func Concat[T any](slice []T, slices ...[]T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -293,7 +300,7 @@ func main() {
|
|||||||
func Count[T comparable](slice []T, item T) int
|
func Count[T comparable](slice []T, item T) int
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -326,7 +333,7 @@ func main() {
|
|||||||
func CountBy[T any](slice []T, predicate func(index int, item T) bool) int
|
func CountBy[T any](slice []T, predicate func(index int, item T) bool) int
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -360,7 +367,7 @@ func main() {
|
|||||||
func Difference[T comparable](slice, comparedSlice []T) []T
|
func Difference[T comparable](slice, comparedSlice []T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -391,7 +398,7 @@ func main() {
|
|||||||
func DifferenceBy[T comparable](slice []T, comparedSlice []T, iteratee func(index int, item T) T) []T
|
func DifferenceBy[T comparable](slice []T, comparedSlice []T, iteratee func(index int, item T) T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -426,7 +433,7 @@ func main() {
|
|||||||
func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(value, otherValue T) bool) []T
|
func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(value, otherValue T) bool) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -461,7 +468,7 @@ func main() {
|
|||||||
func DeleteAt[T any](slice []T, start int, end ...int)
|
func DeleteAt[T any](slice []T, start int, end ...int)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -486,9 +493,10 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="Drop">Drop</span>
|
### <span id="Drop">Drop</span>
|
||||||
|
|
||||||
<p>创建一个切片,当n > 0时从开头删除n个元素,或者当n < 0时从结尾删除n个元素</p>
|
<p>从切片的头部删除n个元素。</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
@@ -496,7 +504,7 @@ func main() {
|
|||||||
func Drop[T any](slice []T, n int) []T
|
func Drop[T any](slice []T, n int) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -506,20 +514,139 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
result1 := slice.Drop([]string{"a", "b", "c"}, 0)
|
result1 := slice.Drop([]string{"a", "b", "c"}, 0)
|
||||||
result2 := slice.Drop([]string{"a", "b", "c"}, 1)
|
result2 := slice.Drop([]string{"a", "b", "c"}, 1)
|
||||||
result3 := slice.Drop([]string{"a", "b", "c"}, -1)
|
result3 := slice.Drop([]string{"a", "b", "c"}, -1)
|
||||||
result4 := slice.Drop([]string{"a", "b", "c"}, 4)
|
result4 := slice.Drop([]string{"a", "b", "c"}, 4)
|
||||||
|
|
||||||
fmt.Println(result1)
|
fmt.Println(result1)
|
||||||
fmt.Println(result2)
|
fmt.Println(result2)
|
||||||
fmt.Println(result3)
|
fmt.Println(result3)
|
||||||
fmt.Println(result4)
|
fmt.Println(result4)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// [a b c]
|
// [a b c]
|
||||||
// [b c]
|
// [b c]
|
||||||
// [a b]
|
// [a b c]
|
||||||
// []
|
// []
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="DropRight">DropRight</span>
|
||||||
|
|
||||||
|
<p>从切片的尾部删除n个元素。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func DropRight[T any](slice []T, n int) []T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := slice.DropRight([]string{"a", "b", "c"}, 0)
|
||||||
|
result2 := slice.DropRight([]string{"a", "b", "c"}, 1)
|
||||||
|
result3 := slice.DropRight([]string{"a", "b", "c"}, -1)
|
||||||
|
result4 := slice.DropRight([]string{"a", "b", "c"}, 4)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [a b c]
|
||||||
|
// [a b]
|
||||||
|
// [a b c]
|
||||||
|
// []
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="DropWhile">DropWhile</span>
|
||||||
|
|
||||||
|
<p>从切片的头部删除n个元素,这个n个元素满足predicate函数返回true。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func DropWhile[T any](slice []T, predicate func(item T) bool) []T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := slice.DropWhile(numbers, func(n int) bool {
|
||||||
|
return n != 2
|
||||||
|
})
|
||||||
|
result2 := slice.DropWhile(numbers, func(n int) bool {
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
result3 := slice.DropWhile(numbers, func(n int) bool {
|
||||||
|
return n == 0
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [2 3 4 5]
|
||||||
|
// []
|
||||||
|
// [1 2 3 4 5]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="DropRightWhile">DropRightWhile</span>
|
||||||
|
|
||||||
|
<p>从切片的尾部删除n个元素,这个n个元素满足predicate函数返回true。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func DropRightWhile[T any](slice []T, predicate func(item T) bool) []T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
numbers := []int{1, 2, 3, 4, 5}
|
||||||
|
|
||||||
|
result1 := slice.DropRightWhile(numbers, func(n int) bool {
|
||||||
|
return n != 2
|
||||||
|
})
|
||||||
|
result2 := slice.DropRightWhile(numbers, func(n int) bool {
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
result3 := slice.DropRightWhile(numbers, func(n int) bool {
|
||||||
|
return n == 0
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [1 2]
|
||||||
|
// []
|
||||||
|
// [1 2 3 4 5]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -533,7 +660,7 @@ func main() {
|
|||||||
func Every[T any](slice []T, predicate func(index int, item T) bool) bool
|
func Every[T any](slice []T, predicate func(index int, item T) bool) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -567,7 +694,7 @@ func main() {
|
|||||||
func Equal[T comparable](slice1, slice2 []T) bool
|
func Equal[T comparable](slice1, slice2 []T) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -602,7 +729,7 @@ func main() {
|
|||||||
func EqualWith[T, U any](slice1 []T, slice2 []U, comparator func(T, U) bool) bool
|
func EqualWith[T, U any](slice1 []T, slice2 []U, comparator func(T, U) bool) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -637,7 +764,7 @@ func main() {
|
|||||||
func Filter[T any](slice []T, predicate func(index int, item T) bool) []T
|
func Filter[T any](slice []T, predicate func(index int, item T) bool) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -671,7 +798,7 @@ func main() {
|
|||||||
func Find[T any](slice []T, predicate func(index int, item T) bool) (*T, bool)
|
func Find[T any](slice []T, predicate func(index int, item T) bool) (*T, bool)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -707,7 +834,7 @@ func main() {
|
|||||||
func FindLast[T any](slice []T, predicate func(index int, item T) bool) (*T, bool)
|
func FindLast[T any](slice []T, predicate func(index int, item T) bool) (*T, bool)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -743,7 +870,7 @@ func main() {
|
|||||||
func Flatten(slice any) any
|
func Flatten(slice any) any
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -773,7 +900,7 @@ func main() {
|
|||||||
func FlattenDeep(slice any) any
|
func FlattenDeep(slice any) any
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -803,7 +930,7 @@ func main() {
|
|||||||
func ForEach[T any](slice []T, iteratee func(index int, item T))
|
func ForEach[T any](slice []T, iteratee func(index int, item T))
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -838,7 +965,7 @@ func main() {
|
|||||||
func GroupBy[T any](slice []T, groupFn func(index int, item T) bool) ([]T, []T)
|
func GroupBy[T any](slice []T, groupFn func(index int, item T) bool) ([]T, []T)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -874,7 +1001,7 @@ func main() {
|
|||||||
func GroupWith[T any, U comparable](slice []T, iteratee func(T) U) map[U][]T
|
func GroupWith[T any, U comparable](slice []T, iteratee func(T) U) map[U][]T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -908,7 +1035,7 @@ func main() {
|
|||||||
func IntSlice(slice any) []int
|
func IntSlice(slice any) []int
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -937,7 +1064,7 @@ func main() {
|
|||||||
func InterfaceSlice(slice any) []any
|
func InterfaceSlice(slice any) []any
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -966,7 +1093,7 @@ func main() {
|
|||||||
func Intersection[T comparable](slices ...[]T) []T
|
func Intersection[T comparable](slices ...[]T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -997,7 +1124,7 @@ func main() {
|
|||||||
func InsertAt[T any](slice []T, index int, value any) []T
|
func InsertAt[T any](slice []T, index int, value any) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1037,7 +1164,7 @@ func main() {
|
|||||||
func IndexOf[T comparable](slice []T, item T) int
|
func IndexOf[T comparable](slice []T, item T) int
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1070,7 +1197,7 @@ func main() {
|
|||||||
func LastIndexOf[T comparable](slice []T, item T) int
|
func LastIndexOf[T comparable](slice []T, item T) int
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1103,7 +1230,7 @@ func main() {
|
|||||||
func Map[T any, U any](slice []T, iteratee func(index int, item T) U) []U
|
func Map[T any, U any](slice []T, iteratee func(index int, item T) U) []U
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1137,7 +1264,7 @@ func main() {
|
|||||||
func Merge[T any](slices ...[]T) []T
|
func Merge[T any](slices ...[]T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1168,7 +1295,7 @@ func main() {
|
|||||||
func Reverse[T any](slice []T)
|
func Reverse[T any](slice []T)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1198,7 +1325,7 @@ func main() {
|
|||||||
func Reduce[T any](slice []T, iteratee func(index int, item1, item2 T) T, initial T) T
|
func Reduce[T any](slice []T, iteratee func(index int, item1, item2 T) T, initial T) T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1232,7 +1359,7 @@ func main() {
|
|||||||
func Replace[T comparable](slice []T, old T, new T, n int) []T
|
func Replace[T comparable](slice []T, old T, new T, n int) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1274,7 +1401,7 @@ func main() {
|
|||||||
func ReplaceAll[T comparable](slice []T, old T, new T) []T
|
func ReplaceAll[T comparable](slice []T, old T, new T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1302,7 +1429,7 @@ func main() {
|
|||||||
func Repeat[T any](item T, n int) []T
|
func Repeat[T any](item T, n int) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1330,7 +1457,7 @@ func main() {
|
|||||||
func Shuffle[T any](slice []T) []T
|
func Shuffle[T any](slice []T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1349,6 +1476,148 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="IsAscending">IsAscending</span>
|
||||||
|
|
||||||
|
<p>检查切片元素是否按升序排列。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func IsAscending[T constraints.Ordered](slice []T) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := slice.IsAscending([]int{1, 2, 3, 4, 5})
|
||||||
|
result2 := slice.IsAscending([]int{5, 4, 3, 2, 1})
|
||||||
|
result3 := slice.IsAscending([]int{2, 1, 3, 4, 5})
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="IsDescending">IsDescending</span>
|
||||||
|
|
||||||
|
<p>检查切片元素是否按降序排列。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func IsDescending[T constraints.Ordered](slice []T) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := slice.IsDescending([]int{5, 4, 3, 2, 1})
|
||||||
|
result2 := slice.IsDescending([]int{1, 2, 3, 4, 5})
|
||||||
|
result3 := slice.IsDescending([]int{2, 1, 3, 4, 5})
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="IsSorted">IsSorted</span>
|
||||||
|
|
||||||
|
<p>检查切片元素是否是有序的(升序或降序)。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func IsSorted[T constraints.Ordered](slice []T) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := slice.IsSorted([]int{5, 4, 3, 2, 1})
|
||||||
|
result2 := slice.IsSorted([]int{1, 2, 3, 4, 5})
|
||||||
|
result3 := slice.IsSorted([]int{2, 1, 3, 4, 5})
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="IsSortedByKey">IsSortedByKey</span>
|
||||||
|
|
||||||
|
<p>通过iteratee函数,检查切片元素是否是有序的。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func IsSortedByKey[T any, K constraints.Ordered](slice []T, iteratee func(item T) K) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := slice.IsSortedByKey([]string{"a", "ab", "abc"}, func(s string) int {
|
||||||
|
return len(s)
|
||||||
|
})
|
||||||
|
result2 := slice.IsSortedByKey([]string{"abc", "ab", "a"}, func(s string) int {
|
||||||
|
return len(s)
|
||||||
|
})
|
||||||
|
result3 := slice.IsSortedByKey([]string{"abc", "a", "ab"}, func(s string) int {
|
||||||
|
return len(s)
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="Sort">Sort</span>
|
### <span id="Sort">Sort</span>
|
||||||
|
|
||||||
<p>对任何有序类型(数字或字符串)的切片进行排序,使用快速排序算法。 默认排序顺序为升序 (asc),如果需要降序,请将参数 `sortOrder` 设置为 `desc`。 Ordered类型:数字(所有整数浮点数)或字符串。</p>
|
<p>对任何有序类型(数字或字符串)的切片进行排序,使用快速排序算法。 默认排序顺序为升序 (asc),如果需要降序,请将参数 `sortOrder` 设置为 `desc`。 Ordered类型:数字(所有整数浮点数)或字符串。</p>
|
||||||
@@ -1359,7 +1628,7 @@ func main() {
|
|||||||
func Sort[T constraints.Ordered](slice []T, sortOrder ...string)
|
func Sort[T constraints.Ordered](slice []T, sortOrder ...string)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1396,7 +1665,7 @@ func main() {
|
|||||||
func SortBy[T any](slice []T, less func(a, b T) bool)
|
func SortBy[T any](slice []T, less func(a, b T) bool)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1443,7 +1712,7 @@ func main() {
|
|||||||
func SortByField(slice any, field string, sortType ...string) error
|
func SortByField(slice any, field string, sortType ...string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1484,7 +1753,7 @@ func main() {
|
|||||||
func Some[T any](slice []T, predicate func(index int, item T) bool) bool
|
func Some[T any](slice []T, predicate func(index int, item T) bool) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1518,7 +1787,7 @@ func main() {
|
|||||||
func StringSlice(slice any) []string
|
func StringSlice(slice any) []string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1547,7 +1816,7 @@ func main() {
|
|||||||
func SymmetricDifference[T comparable](slices ...[]T) []T
|
func SymmetricDifference[T comparable](slices ...[]T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1578,7 +1847,7 @@ func main() {
|
|||||||
func ToSlice[T any](items ...T) []T
|
func ToSlice[T any](items ...T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1606,7 +1875,7 @@ func main() {
|
|||||||
func ToSlicePointer[T any](items ...T) []*T
|
func ToSlicePointer[T any](items ...T) []*T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1641,7 +1910,7 @@ func main() {
|
|||||||
func Unique[T comparable](slice []T) []T
|
func Unique[T comparable](slice []T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1668,7 +1937,7 @@ func main() {
|
|||||||
func UniqueBy[T comparable](slice []T, iteratee func(item T) T) []T
|
func UniqueBy[T comparable](slice []T, iteratee func(item T) T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1699,7 +1968,7 @@ func main() {
|
|||||||
func Union[T comparable](slices ...[]T) []T
|
func Union[T comparable](slices ...[]T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1730,7 +1999,7 @@ func main() {
|
|||||||
func UnionBy[T any, V comparable](predicate func(item T) V, slices ...[]T) []T
|
func UnionBy[T any, V comparable](predicate func(item T) V, slices ...[]T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1763,7 +2032,7 @@ func main() {
|
|||||||
func UpdateAt[T any](slice []T, index int, value T) []T
|
func UpdateAt[T any](slice []T, index int, value T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1803,7 +2072,7 @@ func main() {
|
|||||||
func Without[T comparable](slice []T, items ...T) []T
|
func Without[T comparable](slice []T, items ...T) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -1831,7 +2100,7 @@ func main() {
|
|||||||
func KeyBy[T any, U comparable](slice []T, iteratee func(item T) U) map[U]T
|
func KeyBy[T any, U comparable](slice []T, iteratee func(item T) U) map[U]T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -289,7 +289,7 @@ func main() {
|
|||||||
func GetOsBits() int
|
func GetOsBits() int
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ import (
|
|||||||
func ContainChinese(s string) bool
|
func ContainChinese(s string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -99,7 +99,7 @@ func main() {
|
|||||||
func ContainLetter(str string) bool
|
func ContainLetter(str string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -133,7 +133,7 @@ func main() {
|
|||||||
func ContainLower(str string) bool
|
func ContainLower(str string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -167,7 +167,7 @@ func main() {
|
|||||||
func ContainUpper(str string) bool
|
func ContainUpper(str string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -201,7 +201,7 @@ func main() {
|
|||||||
func IsAlpha(s string) bool
|
func IsAlpha(s string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -235,7 +235,7 @@ func main() {
|
|||||||
func IsAllUpper(str string) bool
|
func IsAllUpper(str string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -269,7 +269,7 @@ func main() {
|
|||||||
func IsAllLower(str string) bool
|
func IsAllLower(str string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -303,7 +303,7 @@ func main() {
|
|||||||
func IsBase64(base64 string) bool
|
func IsBase64(base64 string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -334,7 +334,7 @@ func main() {
|
|||||||
func IsChineseMobile(mobileNum string) bool
|
func IsChineseMobile(mobileNum string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -365,7 +365,7 @@ func main() {
|
|||||||
func IsChineseIdNum(id string) bool
|
func IsChineseIdNum(id string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -396,7 +396,7 @@ func main() {
|
|||||||
func IsChinesePhone(phone string) bool
|
func IsChinesePhone(phone string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -427,7 +427,7 @@ func main() {
|
|||||||
func IsCreditCard(creditCart string) bool
|
func IsCreditCard(creditCart string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -458,7 +458,7 @@ func main() {
|
|||||||
func IsDns(dns string) bool
|
func IsDns(dns string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -492,7 +492,7 @@ func main() {
|
|||||||
func IsEmail(email string) bool
|
func IsEmail(email string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -523,7 +523,7 @@ func main() {
|
|||||||
func IsEmptyString(s string) bool
|
func IsEmptyString(s string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -557,7 +557,7 @@ func main() {
|
|||||||
func IsFloatStr(s string) bool
|
func IsFloatStr(s string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -594,7 +594,7 @@ func main() {
|
|||||||
func IsNumberStr(s string) bool
|
func IsNumberStr(s string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -631,7 +631,7 @@ func main() {
|
|||||||
func IsJSON(str string) bool
|
func IsJSON(str string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -668,7 +668,7 @@ func main() {
|
|||||||
func IsRegexMatch(s, regex string) bool
|
func IsRegexMatch(s, regex string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -699,7 +699,7 @@ func main() {
|
|||||||
func IsIntStr(s string) bool
|
func IsIntStr(s string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -736,7 +736,7 @@ func main() {
|
|||||||
func IsIp(ipstr string) bool
|
func IsIp(ipstr string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -773,7 +773,7 @@ func main() {
|
|||||||
func IsIpV4(ipstr string) bool
|
func IsIpV4(ipstr string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -804,7 +804,7 @@ func main() {
|
|||||||
func IsIpV6(ipstr string) bool
|
func IsIpV6(ipstr string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -835,7 +835,7 @@ func main() {
|
|||||||
func IsStrongPassword(password string, length int) bool
|
func IsStrongPassword(password string, length int) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -866,7 +866,7 @@ func main() {
|
|||||||
func IsUrl(str string) bool
|
func IsUrl(str string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -901,7 +901,7 @@ func main() {
|
|||||||
func IsWeakPassword(password string, length int) bool
|
func IsWeakPassword(password string, length int) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -932,7 +932,7 @@ func main() {
|
|||||||
func IsZeroValue(value any) bool
|
func IsZeroValue(value any) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
@@ -969,7 +969,7 @@ func main() {
|
|||||||
func IsGBK(data []byte) bool
|
func IsGBK(data []byte) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
|
|||||||
430
docs/xerror.md
430
docs/xerror.md
@@ -22,20 +22,40 @@ import (
|
|||||||
|
|
||||||
## Index
|
## Index
|
||||||
|
|
||||||
|
- [New](#New)
|
||||||
|
- [Wrap](#Wrap)
|
||||||
- [Unwrap](#Unwrap)
|
- [Unwrap](#Unwrap)
|
||||||
|
- [XError_Wrap](#XError_Wrap)
|
||||||
|
- [XError_Unwrap](#XError_Unwrap)
|
||||||
|
- [XError_With](#XError_With)
|
||||||
|
- [XError_Is](#XError_Is)
|
||||||
|
- [XError_Id](#XError_Id)
|
||||||
|
- [XError_Values](#XError_Values)
|
||||||
|
- [XError_StackTrace](#XError_StackTrace)
|
||||||
|
- [XError_Info](#XError_Info)
|
||||||
|
- [XError_Error](#XError_Error)
|
||||||
|
- [TryUnwrap](#TryUnwrap)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
### <span id="Unwrap">Unwrap</span>
|
### <span id="New">New</span>
|
||||||
|
|
||||||
<p>Unwrap if err is nil then it returns a valid value. If err is not nil, Unwrap panics with err.</p>
|
<p>Creates a new XError pointer instance with message.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func Unwrap[T any](val T, err error) T
|
type XError struct {
|
||||||
|
id string
|
||||||
|
message string
|
||||||
|
stack *stack
|
||||||
|
cause error
|
||||||
|
values map[string]any
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(format string, args ...any) *XError
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
@@ -49,7 +69,407 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
result1 := xerror.Unwrap(strconv.Atoi("42"))
|
err := xerror.New("error")
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// error
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Wrap">Wrap</span>
|
||||||
|
|
||||||
|
<p>Creates a new XError pointer instance based on error object, and add message.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Wrap(cause error, message ...any) *XError
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := xerror.New("wrong password")
|
||||||
|
wrapErr := xerror.Wrap(err, "error")
|
||||||
|
|
||||||
|
fmt.Println(wrapErr.Error())
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// error: wrong password
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Unwrap">Unwrap</span>
|
||||||
|
|
||||||
|
<p>Returns unwrapped XError from err by errors.As. If no XError, returns nil.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Unwrap(err error) *XError
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err1 := xerror.New("error").With("level", "high")
|
||||||
|
wrapErr := errors.Wrap(err1, "oops")
|
||||||
|
|
||||||
|
err := xerror.Unwrap(err1)
|
||||||
|
|
||||||
|
values := err.Values()
|
||||||
|
fmt.Println(values["level"])
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// high
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="XError_Wrap">XError_Wrap</span>
|
||||||
|
|
||||||
|
<p>Creates a new XError and copy message and id to new one.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (e *XError) Wrap(cause error) *XError
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := xerror.New("wrong password")
|
||||||
|
wrapErr := xerror.Wrap(err, "error")
|
||||||
|
|
||||||
|
fmt.Println(wrapErr.Error())
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// error: wrong password
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="XError_Unwrap">XError_Unwrap</span>
|
||||||
|
|
||||||
|
<p>Compatible with github.com/pkg/errors.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (e *XError) Unwrap() error
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err1 := xerror.New("error").With("level", "high")
|
||||||
|
err2 := err1.Wrap(errors.New("invalid username"))
|
||||||
|
|
||||||
|
err := err2.Unwrap()
|
||||||
|
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// invalid username
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="XError_With">XError_With</span>
|
||||||
|
|
||||||
|
<p>Adds key and value related to the XError object.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (e *XError) With(key string, value any) *XError
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := xerror.New("error").With("level", "high")
|
||||||
|
|
||||||
|
errLevel := err.Values()["level"]
|
||||||
|
|
||||||
|
fmt.Println(errLevel)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// high
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="XError_Id">XError_Id</span>
|
||||||
|
|
||||||
|
<p>Sets XError object id to check equality in XError.Is.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (e *XError) Id(id string) *XError
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err1 := xerror.New("error").Id("e001")
|
||||||
|
err2 := xerror.New("error").Id("e001")
|
||||||
|
err3 := xerror.New("error").Id("e003")
|
||||||
|
|
||||||
|
equal := err1.Is(err2)
|
||||||
|
notEqual := err1.Is(err3)
|
||||||
|
|
||||||
|
fmt.Println(equal)
|
||||||
|
fmt.Println(notEqual)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="XError_Is">XError_Is</span>
|
||||||
|
|
||||||
|
<p>Checks if target error is XError and Error.id of two errors are matched.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (e *XError) Is(target error) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err1 := xerror.New("error").Id("e001")
|
||||||
|
err2 := xerror.New("error").Id("e001")
|
||||||
|
err3 := xerror.New("error").Id("e003")
|
||||||
|
|
||||||
|
equal := err1.Is(err2)
|
||||||
|
notEqual := err1.Is(err3)
|
||||||
|
|
||||||
|
fmt.Println(equal)
|
||||||
|
fmt.Println(notEqual)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="XError_Values">XError_Values</span>
|
||||||
|
|
||||||
|
<p>Returns map of key and value that is set by With. All wrapped xerror.XError key and values will be merged. Key and values of wrapped error is overwritten by upper xerror.XError.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (e *XError) Values() map[string]any
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := xerror.New("error").With("level", "high")
|
||||||
|
|
||||||
|
errLevel := err.Values()["level"]
|
||||||
|
|
||||||
|
fmt.Println(errLevel)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// high
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="XError_StackTrace">XError_StackTrace</span>
|
||||||
|
|
||||||
|
<p>Returns stack trace which is compatible with pkg/errors.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (e *XError) StackTrace() StackTrace
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := xerror.New("error")
|
||||||
|
|
||||||
|
stacks := err.Stacks()
|
||||||
|
|
||||||
|
fmt.Println(stacks[0].Func)
|
||||||
|
fmt.Println(stacks[0].Line)
|
||||||
|
|
||||||
|
containFile := strings.Contains(stacks[0].File, "xxx.go")
|
||||||
|
fmt.Println(containFile)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="XError_Info">XError_Info</span>
|
||||||
|
|
||||||
|
<p>Returns information of xerror, which can be printed.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (e *XError) Info() *errInfo
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
cause := errors.New("error")
|
||||||
|
err := xerror.Wrap(cause, "invalid username").Id("e001").With("level", "high")
|
||||||
|
|
||||||
|
errInfo := err.Info()
|
||||||
|
|
||||||
|
fmt.Println(errInfo.Id)
|
||||||
|
fmt.Println(errInfo.Cause)
|
||||||
|
fmt.Println(errInfo.Values["level"])
|
||||||
|
fmt.Println(errInfo.Message)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// e001
|
||||||
|
// error
|
||||||
|
// high
|
||||||
|
// invalid username
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="XError_Error">XError_Error</span>
|
||||||
|
|
||||||
|
<p>Error implements standard error interface.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (e *XError) Error() string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := New("error")
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// error
|
||||||
|
}
|
||||||
|
```
|
||||||
|
### <span id="TryUnwrap">TryUnwrap</span>
|
||||||
|
|
||||||
|
<p>TryUnwrap if err is nil then it returns a valid value. If err is not nil, Unwrap panics with err.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func TryUnwrap[T any](val T, err error) T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := xerror.TryUnwrap(strconv.Atoi("42"))
|
||||||
fmt.Println(result1)
|
fmt.Println(result1)
|
||||||
|
|
||||||
_, err := strconv.Atoi("4o2")
|
_, err := strconv.Atoi("4o2")
|
||||||
@@ -59,7 +479,7 @@ func main() {
|
|||||||
fmt.Println(result2)
|
fmt.Println(result2)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
xerror.Unwrap(strconv.Atoi("4o2"))
|
xerror.TryUnwrap(strconv.Atoi("4o2"))
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// 42
|
// 42
|
||||||
|
|||||||
@@ -22,23 +22,43 @@ import (
|
|||||||
|
|
||||||
## 目录
|
## 目录
|
||||||
|
|
||||||
|
- [New](#New)
|
||||||
|
- [Wrap](#Wrap)
|
||||||
- [Unwrap](#Unwrap)
|
- [Unwrap](#Unwrap)
|
||||||
|
- [XError_Wrap](#XError_Wrap)
|
||||||
|
- [XError_Unwrap](#XError_Unwrap)
|
||||||
|
- [XError_With](#XError_With)
|
||||||
|
- [XError_Is](#XError_Is)
|
||||||
|
- [XError_Id](#XError_Id)
|
||||||
|
- [XError_Values](#XError_Values)
|
||||||
|
- [XError_StackTrace](#XError_StackTrace)
|
||||||
|
- [XError_Info](#XError_Info)
|
||||||
|
- [XError_Error](#XError_Error)
|
||||||
|
- [TryUnwrap](#TryUnwrap)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 文档
|
## 文档
|
||||||
|
|
||||||
### <span id="Unwrap">Unwrap</span>
|
### <span id="New">New</span>
|
||||||
|
|
||||||
<p>检查error, 如果err为nil则展开,则它返回一个有效值,如果err不是nil则Unwrap使用err发生panic。</p>
|
<p>创建XError对象实例。</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func Unwrap[T any](val T, err error) T
|
type XError struct {
|
||||||
|
id string
|
||||||
|
message string
|
||||||
|
stack *stack
|
||||||
|
cause error
|
||||||
|
values map[string]any
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(format string, args ...any) *XError
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>示例:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -49,7 +69,408 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
result1 := xerror.Unwrap(strconv.Atoi("42"))
|
err := xerror.New("error")
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// error
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Wrap">Wrap</span>
|
||||||
|
|
||||||
|
<p>根据error对象创建XError对象实例,可添加message。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Wrap(cause error, message ...any) *XError
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := xerror.New("wrong password")
|
||||||
|
wrapErr := xerror.Wrap(err, "error")
|
||||||
|
|
||||||
|
fmt.Println(wrapErr.Error())
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// error: wrong password
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Unwrap">Unwrap</span>
|
||||||
|
|
||||||
|
<p>从error对象中解构出XError。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Unwrap(err error) *XError
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err1 := xerror.New("error").With("level", "high")
|
||||||
|
wrapErr := errors.Wrap(err1, "oops")
|
||||||
|
|
||||||
|
err := xerror.Unwrap(err1)
|
||||||
|
|
||||||
|
values := err.Values()
|
||||||
|
fmt.Println(values["level"])
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// high
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="XError_Wrap">XError_Wrap</span>
|
||||||
|
|
||||||
|
<p>创建新的XError对象并将消息和id复制到新的对象中。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (e *XError) Wrap(cause error) *XError
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := xerror.New("wrong password")
|
||||||
|
wrapErr := xerror.Wrap(err, "error")
|
||||||
|
|
||||||
|
fmt.Println(wrapErr.Error())
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// error: wrong password
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="XError_Unwrap">XError_Unwrap</span>
|
||||||
|
|
||||||
|
<p>解构XEerror为error对象。适配github.com/pkg/errors。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (e *XError) Unwrap() error
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err1 := xerror.New("error").With("level", "high")
|
||||||
|
err2 := err1.Wrap(errors.New("invalid username"))
|
||||||
|
|
||||||
|
err := err2.Unwrap()
|
||||||
|
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// invalid username
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="XError_With">XError_With</span>
|
||||||
|
|
||||||
|
<p>添加与XError对象的键和值。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (e *XError) With(key string, value any) *XError
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := xerror.New("error").With("level", "high")
|
||||||
|
|
||||||
|
errLevel := err.Values()["level"]
|
||||||
|
|
||||||
|
fmt.Println(errLevel)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// high
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="XError_Id">XError_Id</span>
|
||||||
|
|
||||||
|
<p>设置XError对象的id。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (e *XError) Id(id string) *XError
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err1 := xerror.New("error").Id("e001")
|
||||||
|
err2 := xerror.New("error").Id("e001")
|
||||||
|
err3 := xerror.New("error").Id("e003")
|
||||||
|
|
||||||
|
equal := err1.Is(err2)
|
||||||
|
notEqual := err1.Is(err3)
|
||||||
|
|
||||||
|
fmt.Println(equal)
|
||||||
|
fmt.Println(notEqual)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="XError_Is">XError_Is</span>
|
||||||
|
|
||||||
|
<p>检查目标error是否为XError,两个错误中的error.id是否匹配。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (e *XError) Is(target error) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err1 := xerror.New("error").Id("e001")
|
||||||
|
err2 := xerror.New("error").Id("e001")
|
||||||
|
err3 := xerror.New("error").Id("e003")
|
||||||
|
|
||||||
|
equal := err1.Is(err2)
|
||||||
|
notEqual := err1.Is(err3)
|
||||||
|
|
||||||
|
fmt.Println(equal)
|
||||||
|
fmt.Println(notEqual)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="XError_Values">XError_Values</span>
|
||||||
|
|
||||||
|
<p>返回由With设置的键和值的映射。将合并所有XError键和值。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (e *XError) Values() map[string]any
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := xerror.New("error").With("level", "high")
|
||||||
|
|
||||||
|
errLevel := err.Values()["level"]
|
||||||
|
|
||||||
|
fmt.Println(errLevel)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// high
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="XError_StackTrace">XError_StackTrace</span>
|
||||||
|
|
||||||
|
<p>返回与pkg/error兼容的堆栈信息。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (e *XError) StackTrace() StackTrace
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := xerror.New("error")
|
||||||
|
|
||||||
|
stacks := err.Stacks()
|
||||||
|
|
||||||
|
fmt.Println(stacks[0].Func)
|
||||||
|
fmt.Println(stacks[0].Line)
|
||||||
|
|
||||||
|
containFile := strings.Contains(stacks[0].File, "xxx.go")
|
||||||
|
fmt.Println(containFile)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="XError_Info">XError_Info</span>
|
||||||
|
|
||||||
|
<p>返回可打印的XError对象信息。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (e *XError) Info() *errInfo
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
cause := errors.New("error")
|
||||||
|
err := xerror.Wrap(cause, "invalid username").Id("e001").With("level", "high")
|
||||||
|
|
||||||
|
errInfo := err.Info()
|
||||||
|
|
||||||
|
fmt.Println(errInfo.Id)
|
||||||
|
fmt.Println(errInfo.Cause)
|
||||||
|
fmt.Println(errInfo.Values["level"])
|
||||||
|
fmt.Println(errInfo.Message)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// e001
|
||||||
|
// error
|
||||||
|
// high
|
||||||
|
// invalid username
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="XError_Error">XError_Error</span>
|
||||||
|
|
||||||
|
<p>实现标准库的error接口。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (e *XError) Error() string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := New("error")
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// error
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="TryUnwrap">TryUnwrap</span>
|
||||||
|
|
||||||
|
<p>检查error, 如果err为nil则展开,则它返回一个有效值,如果err不是nil则TryUnwrap使用err发生panic。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func TryUnwrap[T any](val T, err error) T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/xerror"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := xerror.TryUnwrap(strconv.Atoi("42"))
|
||||||
fmt.Println(result1)
|
fmt.Println(result1)
|
||||||
|
|
||||||
_, err := strconv.Atoi("4o2")
|
_, err := strconv.Atoi("4o2")
|
||||||
@@ -59,7 +480,7 @@ func main() {
|
|||||||
fmt.Println(result2)
|
fmt.Println(result2)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
xerror.Unwrap(strconv.Atoi("4o2"))
|
xerror.TryUnwrap(strconv.Atoi("4o2"))
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// 42
|
// 42
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
NUMERAL = "0123456789"
|
Numeral = "0123456789"
|
||||||
LOWER_LETTERS = "abcdefghijklmnopqrstuvwxyz"
|
LowwerLetters = "abcdefghijklmnopqrstuvwxyz"
|
||||||
UPPER_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
UpperLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
LETTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
Letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RandInt generate random int between min and max, maybe min, not be max.
|
// RandInt generate random int between min and max, maybe min, not be max.
|
||||||
@@ -51,31 +51,31 @@ func RandBytes(length int) []byte {
|
|||||||
// RandString generate random string of specified length.
|
// RandString generate random string of specified length.
|
||||||
// Play: https://go.dev/play/p/W2xvRUXA7Mi
|
// Play: https://go.dev/play/p/W2xvRUXA7Mi
|
||||||
func RandString(length int) string {
|
func RandString(length int) string {
|
||||||
return random(LETTERS, length)
|
return random(Letters, length)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RandUpper generate a random upper case string.
|
// RandUpper generate a random upper case string.
|
||||||
// Play: https://go.dev/play/p/29QfOh0DVuh
|
// Play: https://go.dev/play/p/29QfOh0DVuh
|
||||||
func RandUpper(length int) string {
|
func RandUpper(length int) string {
|
||||||
return random(UPPER_LETTERS, length)
|
return random(UpperLetters, length)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RandLower generate a random lower case string.
|
// RandLower generate a random lower case string.
|
||||||
// Play: https://go.dev/play/p/XJtZ471cmtI
|
// Play: https://go.dev/play/p/XJtZ471cmtI
|
||||||
func RandLower(length int) string {
|
func RandLower(length int) string {
|
||||||
return random(LOWER_LETTERS, length)
|
return random(LowwerLetters, length)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RandNumeral generate a random numeral string of specified length.
|
// RandNumeral generate a random numeral string of specified length.
|
||||||
// Play: https://go.dev/play/p/g4JWVpHsJcf
|
// Play: https://go.dev/play/p/g4JWVpHsJcf
|
||||||
func RandNumeral(length int) string {
|
func RandNumeral(length int) string {
|
||||||
return random(NUMERAL, length)
|
return random(Numeral, length)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RandNumeralOrLetter generate a random numeral or letter string.
|
// RandNumeralOrLetter generate a random numeral or letter string.
|
||||||
// Play: https://go.dev/play/p/19CEQvpx2jD
|
// Play: https://go.dev/play/p/19CEQvpx2jD
|
||||||
func RandNumeralOrLetter(length int) string {
|
func RandNumeralOrLetter(length int) string {
|
||||||
return random(NUMERAL+LETTERS, length)
|
return random(Numeral+Letters, length)
|
||||||
}
|
}
|
||||||
|
|
||||||
// random generate a random string based on given string range.
|
// random generate a random string based on given string range.
|
||||||
|
|||||||
125
slice/slice.go
125
slice/slice.go
@@ -6,7 +6,6 @@ package slice
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
@@ -559,24 +558,72 @@ func DeleteAt[T any](slice []T, start int, end ...int) []T {
|
|||||||
return slice
|
return slice
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drop creates a slice with `n` elements dropped from the beginning when n > 0, or `n` elements dropped from the ending when n < 0.
|
// Drop drop n elements from the start of a slice.
|
||||||
// Play: https://go.dev/play/p/pJ-d6MUWcvK
|
// Play: https://go.dev/play/p/pJ-d6MUWcvK
|
||||||
func Drop[T any](slice []T, n int) []T {
|
func Drop[T any](slice []T, n int) []T {
|
||||||
size := len(slice)
|
size := len(slice)
|
||||||
|
|
||||||
if size == 0 || n == 0 {
|
if size <= n {
|
||||||
return slice
|
|
||||||
}
|
|
||||||
|
|
||||||
if math.Abs(float64(n)) >= float64(size) {
|
|
||||||
return []T{}
|
return []T{}
|
||||||
}
|
}
|
||||||
|
|
||||||
if n < 0 {
|
if n <= 0 {
|
||||||
return slice[0 : size+n]
|
return slice
|
||||||
}
|
}
|
||||||
|
|
||||||
return slice[n:size]
|
result := make([]T, 0, size-n)
|
||||||
|
|
||||||
|
return append(result, slice[n:]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DropRight drop n elements from the end of a slice.
|
||||||
|
// Play: todo
|
||||||
|
func DropRight[T any](slice []T, n int) []T {
|
||||||
|
size := len(slice)
|
||||||
|
|
||||||
|
if size <= n {
|
||||||
|
return []T{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if n <= 0 {
|
||||||
|
return slice
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make([]T, 0, size-n)
|
||||||
|
|
||||||
|
return append(result, slice[:size-n]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DropWhile drop n elements from the start of a slice while predicate function returns true.
|
||||||
|
// Play: todo
|
||||||
|
func DropWhile[T any](slice []T, predicate func(item T) bool) []T {
|
||||||
|
i := 0
|
||||||
|
|
||||||
|
for ; i < len(slice); i++ {
|
||||||
|
if !predicate(slice[i]) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make([]T, 0, len(slice)-i)
|
||||||
|
|
||||||
|
return append(result, slice[i:]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DropRightWhile drop n elements from the end of a slice while predicate function returns true.
|
||||||
|
// Play: todo
|
||||||
|
func DropRightWhile[T any](slice []T, predicate func(item T) bool) []T {
|
||||||
|
i := len(slice) - 1
|
||||||
|
|
||||||
|
for ; i >= 0; i-- {
|
||||||
|
if !predicate(slice[i]) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make([]T, 0, i+1)
|
||||||
|
|
||||||
|
return append(result, slice[:i+1]...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InsertAt insert the value or other slice into slice at index.
|
// InsertAt insert the value or other slice into slice at index.
|
||||||
@@ -783,6 +830,64 @@ func Shuffle[T any](slice []T) []T {
|
|||||||
return slice
|
return slice
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsAscending checks if a slice is ascending order.
|
||||||
|
// Play: todo
|
||||||
|
func IsAscending[T constraints.Ordered](slice []T) bool {
|
||||||
|
for i := 1; i < len(slice); i++ {
|
||||||
|
if slice[i-1] > slice[i] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsDescending checks if a slice is descending order.
|
||||||
|
// Play: todo
|
||||||
|
func IsDescending[T constraints.Ordered](slice []T) bool {
|
||||||
|
for i := 1; i < len(slice); i++ {
|
||||||
|
if slice[i-1] < slice[i] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsSorted checks if a slice is sorted(ascending or descending).
|
||||||
|
// Play: todo
|
||||||
|
func IsSorted[T constraints.Ordered](slice []T) bool {
|
||||||
|
return IsAscending(slice) || IsDescending(slice)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsSortedByKey checks if a slice is sorted by iteratee function.
|
||||||
|
// Play: todo
|
||||||
|
func IsSortedByKey[T any, K constraints.Ordered](slice []T, iteratee func(item T) K) bool {
|
||||||
|
size := len(slice)
|
||||||
|
|
||||||
|
isAscending := func(data []T) bool {
|
||||||
|
for i := 0; i < size-1; i++ {
|
||||||
|
if iteratee(data[i]) > iteratee(data[i+1]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
isDescending := func(data []T) bool {
|
||||||
|
for i := 0; i < size-1; i++ {
|
||||||
|
if iteratee(data[i]) < iteratee(data[i+1]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return isAscending(slice) || isDescending(slice)
|
||||||
|
}
|
||||||
|
|
||||||
// Sort sorts a slice of any ordered type(number or string), use quick sort algrithm.
|
// Sort sorts a slice of any ordered type(number or string), use quick sort algrithm.
|
||||||
// default sort order is ascending (asc), if want descending order, set param `sortOrder` to `desc`.
|
// default sort order is ascending (asc), if want descending order, set param `sortOrder` to `desc`.
|
||||||
// Play: https://go.dev/play/p/V9AVjzf_4Fk
|
// Play: https://go.dev/play/p/V9AVjzf_4Fk
|
||||||
|
|||||||
@@ -482,10 +482,74 @@ func ExampleDrop() {
|
|||||||
// Output:
|
// Output:
|
||||||
// [a b c]
|
// [a b c]
|
||||||
// [b c]
|
// [b c]
|
||||||
// [a b]
|
// [a b c]
|
||||||
// []
|
// []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleDropRight() {
|
||||||
|
result1 := DropRight([]string{"a", "b", "c"}, 0)
|
||||||
|
result2 := DropRight([]string{"a", "b", "c"}, 1)
|
||||||
|
result3 := DropRight([]string{"a", "b", "c"}, -1)
|
||||||
|
result4 := DropRight([]string{"a", "b", "c"}, 4)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [a b c]
|
||||||
|
// [a b]
|
||||||
|
// [a b c]
|
||||||
|
// []
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleDropWhile() {
|
||||||
|
numbers := []int{1, 2, 3, 4, 5}
|
||||||
|
|
||||||
|
result1 := DropWhile(numbers, func(n int) bool {
|
||||||
|
return n != 2
|
||||||
|
})
|
||||||
|
result2 := DropWhile(numbers, func(n int) bool {
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
result3 := DropWhile(numbers, func(n int) bool {
|
||||||
|
return n == 0
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [2 3 4 5]
|
||||||
|
// []
|
||||||
|
// [1 2 3 4 5]
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleDropRightWhile() {
|
||||||
|
numbers := []int{1, 2, 3, 4, 5}
|
||||||
|
|
||||||
|
result1 := DropRightWhile(numbers, func(n int) bool {
|
||||||
|
return n != 2
|
||||||
|
})
|
||||||
|
result2 := DropRightWhile(numbers, func(n int) bool {
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
result3 := DropRightWhile(numbers, func(n int) bool {
|
||||||
|
return n == 0
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [1 2]
|
||||||
|
// []
|
||||||
|
// [1 2 3 4 5]
|
||||||
|
}
|
||||||
|
|
||||||
func ExampleInsertAt() {
|
func ExampleInsertAt() {
|
||||||
result1 := InsertAt([]string{"a", "b", "c"}, 0, "1")
|
result1 := InsertAt([]string{"a", "b", "c"}, 0, "1")
|
||||||
result2 := InsertAt([]string{"a", "b", "c"}, 1, "1")
|
result2 := InsertAt([]string{"a", "b", "c"}, 1, "1")
|
||||||
@@ -621,6 +685,75 @@ func ExampleReverse() {
|
|||||||
// [d c b a]
|
// [d c b a]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleIsAscending() {
|
||||||
|
|
||||||
|
result1 := IsAscending([]int{1, 2, 3, 4, 5})
|
||||||
|
result2 := IsAscending([]int{5, 4, 3, 2, 1})
|
||||||
|
result3 := IsAscending([]int{2, 1, 3, 4, 5})
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleIsDescending() {
|
||||||
|
|
||||||
|
result1 := IsDescending([]int{5, 4, 3, 2, 1})
|
||||||
|
result2 := IsDescending([]int{1, 2, 3, 4, 5})
|
||||||
|
result3 := IsDescending([]int{2, 1, 3, 4, 5})
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleIsSorted() {
|
||||||
|
|
||||||
|
result1 := IsSorted([]int{1, 2, 3, 4, 5})
|
||||||
|
result2 := IsSorted([]int{5, 4, 3, 2, 1})
|
||||||
|
result3 := IsSorted([]int{2, 1, 3, 4, 5})
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleIsSortedByKey() {
|
||||||
|
result1 := IsSortedByKey([]string{"a", "ab", "abc"}, func(s string) int {
|
||||||
|
return len(s)
|
||||||
|
})
|
||||||
|
result2 := IsSortedByKey([]string{"abc", "ab", "a"}, func(s string) int {
|
||||||
|
return len(s)
|
||||||
|
})
|
||||||
|
result3 := IsSortedByKey([]string{"abc", "a", "ab"}, func(s string) int {
|
||||||
|
return len(s)
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
|
||||||
func ExampleSort() {
|
func ExampleSort() {
|
||||||
nums := []int{1, 4, 3, 2, 5}
|
nums := []int{1, 4, 3, 2, 5}
|
||||||
|
|
||||||
|
|||||||
@@ -377,7 +377,7 @@ func TestDeleteAt(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDrop(t *testing.T) {
|
func TestDrop(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestInterfaceSlice")
|
assert := internal.NewAssert(t, "TestDrop")
|
||||||
|
|
||||||
assert.Equal([]int{}, Drop([]int{}, 0))
|
assert.Equal([]int{}, Drop([]int{}, 0))
|
||||||
assert.Equal([]int{}, Drop([]int{}, 1))
|
assert.Equal([]int{}, Drop([]int{}, 1))
|
||||||
@@ -388,9 +388,64 @@ func TestDrop(t *testing.T) {
|
|||||||
assert.Equal([]int{}, Drop([]int{1, 2, 3, 4, 5}, 5))
|
assert.Equal([]int{}, Drop([]int{1, 2, 3, 4, 5}, 5))
|
||||||
assert.Equal([]int{}, Drop([]int{1, 2, 3, 4, 5}, 6))
|
assert.Equal([]int{}, Drop([]int{1, 2, 3, 4, 5}, 6))
|
||||||
|
|
||||||
assert.Equal([]int{1, 2, 3, 4}, Drop([]int{1, 2, 3, 4, 5}, -1))
|
assert.Equal([]int{1, 2, 3, 4, 5}, Drop([]int{1, 2, 3, 4, 5}, -1))
|
||||||
assert.Equal([]int{}, Drop([]int{1, 2, 3, 4, 5}, -6))
|
}
|
||||||
assert.Equal([]int{}, Drop([]int{1, 2, 3, 4, 5}, -6))
|
|
||||||
|
func TestDropRight(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestDropRight")
|
||||||
|
|
||||||
|
assert.Equal([]int{}, DropRight([]int{}, 0))
|
||||||
|
assert.Equal([]int{}, DropRight([]int{}, 1))
|
||||||
|
assert.Equal([]int{}, DropRight([]int{}, -1))
|
||||||
|
|
||||||
|
assert.Equal([]int{1, 2, 3, 4, 5}, DropRight([]int{1, 2, 3, 4, 5}, 0))
|
||||||
|
assert.Equal([]int{1, 2, 3, 4}, DropRight([]int{1, 2, 3, 4, 5}, 1))
|
||||||
|
assert.Equal([]int{}, DropRight([]int{1, 2, 3, 4, 5}, 5))
|
||||||
|
assert.Equal([]int{}, DropRight([]int{1, 2, 3, 4, 5}, 6))
|
||||||
|
|
||||||
|
assert.Equal([]int{1, 2, 3, 4, 5}, DropRight([]int{1, 2, 3, 4, 5}, -1))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDropWhile(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestDropWhile")
|
||||||
|
|
||||||
|
numbers := []int{1, 2, 3, 4, 5}
|
||||||
|
|
||||||
|
r1 := DropWhile(numbers, func(n int) bool {
|
||||||
|
return n != 2
|
||||||
|
})
|
||||||
|
assert.Equal([]int{2, 3, 4, 5}, r1)
|
||||||
|
|
||||||
|
r2 := DropWhile(numbers, func(n int) bool {
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
assert.Equal([]int{}, r2)
|
||||||
|
|
||||||
|
r3 := DropWhile(numbers, func(n int) bool {
|
||||||
|
return n == 0
|
||||||
|
})
|
||||||
|
assert.Equal([]int{1, 2, 3, 4, 5}, r3)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDropRightWhile(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestDropRightWhile")
|
||||||
|
|
||||||
|
numbers := []int{1, 2, 3, 4, 5}
|
||||||
|
|
||||||
|
r1 := DropRightWhile(numbers, func(n int) bool {
|
||||||
|
return n != 2
|
||||||
|
})
|
||||||
|
assert.Equal([]int{1, 2}, r1)
|
||||||
|
|
||||||
|
r2 := DropRightWhile(numbers, func(n int) bool {
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
assert.Equal([]int{}, r2)
|
||||||
|
|
||||||
|
r3 := DropRightWhile(numbers, func(n int) bool {
|
||||||
|
return n == 0
|
||||||
|
})
|
||||||
|
assert.Equal([]int{1, 2, 3, 4, 5}, r3)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInsertAt(t *testing.T) {
|
func TestInsertAt(t *testing.T) {
|
||||||
@@ -548,6 +603,46 @@ func TestDifferenceBy(t *testing.T) {
|
|||||||
assert.Equal([]int{1, 2}, DifferenceBy(s1, s2, addOne))
|
assert.Equal([]int{1, 2}, DifferenceBy(s1, s2, addOne))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIsAscending(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestIsAscending")
|
||||||
|
|
||||||
|
assert.Equal(true, IsAscending([]int{1, 2, 3, 4, 5}))
|
||||||
|
assert.Equal(false, IsAscending([]int{5, 4, 3, 2, 1}))
|
||||||
|
assert.Equal(false, IsAscending([]int{2, 1, 3, 4, 5}))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsDescending(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestIsDescending")
|
||||||
|
|
||||||
|
assert.Equal(true, IsDescending([]int{5, 4, 3, 2, 1}))
|
||||||
|
assert.Equal(false, IsDescending([]int{1, 2, 3, 4, 5}))
|
||||||
|
assert.Equal(false, IsDescending([]int{2, 1, 3, 4, 5}))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsSorted(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestIsSorted")
|
||||||
|
|
||||||
|
assert.Equal(true, IsSorted([]int{5, 4, 3, 2, 1}))
|
||||||
|
assert.Equal(true, IsSorted([]int{1, 2, 3, 4, 5}))
|
||||||
|
assert.Equal(false, IsSorted([]int{2, 1, 3, 4, 5}))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsSortedByKey(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestIsSortedByKey")
|
||||||
|
|
||||||
|
assert.Equal(true, IsSortedByKey([]string{"a", "ab", "abc"}, func(s string) int {
|
||||||
|
return len(s)
|
||||||
|
}))
|
||||||
|
|
||||||
|
assert.Equal(true, IsSortedByKey([]string{"abc", "ab", "a"}, func(s string) int {
|
||||||
|
return len(s)
|
||||||
|
}))
|
||||||
|
|
||||||
|
assert.Equal(false, IsSortedByKey([]string{"abc", "a", "ab"}, func(s string) int {
|
||||||
|
return len(s)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
func TestSort(t *testing.T) {
|
func TestSort(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestSort")
|
assert := internal.NewAssert(t, "TestSort")
|
||||||
|
|
||||||
|
|||||||
182
stream/stream.go
182
stream/stream.go
@@ -10,6 +10,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
"golang.org/x/exp/constraints"
|
"golang.org/x/exp/constraints"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -23,7 +24,7 @@ import (
|
|||||||
// Map(mapper func(item T) T) StreamI[T]
|
// Map(mapper func(item T) T) StreamI[T]
|
||||||
// Peek(consumer func(item T)) StreamI[T]
|
// Peek(consumer func(item T)) StreamI[T]
|
||||||
|
|
||||||
// Sort(less func(a, b T) bool) StreamI[T]
|
// Sorted(less func(a, b T) bool) StreamI[T]
|
||||||
// Max(less func(a, b T) bool) (T, bool)
|
// Max(less func(a, b T) bool) (T, bool)
|
||||||
// Min(less func(a, b T) bool) (T, bool)
|
// Min(less func(a, b T) bool) (T, bool)
|
||||||
|
|
||||||
@@ -34,7 +35,7 @@ import (
|
|||||||
// AnyMatch(predicate func(item T) bool) bool
|
// AnyMatch(predicate func(item T) bool) bool
|
||||||
// NoneMatch(predicate func(item T) bool) bool
|
// NoneMatch(predicate func(item T) bool) bool
|
||||||
// ForEach(consumer func(item T))
|
// ForEach(consumer func(item T))
|
||||||
// Reduce(accumulator func(a, b T) T) (T, bool)
|
// Reduce(init T, accumulator func(a, b T) T) T
|
||||||
// Count() int
|
// Count() int
|
||||||
|
|
||||||
// FindFirst() (T, bool)
|
// FindFirst() (T, bool)
|
||||||
@@ -43,7 +44,7 @@ import (
|
|||||||
|
|
||||||
// // part of methods custom extension
|
// // part of methods custom extension
|
||||||
// Reverse() StreamI[T]
|
// Reverse() StreamI[T]
|
||||||
// Range(start, end int64) StreamI[T]
|
// Range(start, end int) StreamI[T]
|
||||||
// Concat(streams ...StreamI[T]) StreamI[T]
|
// Concat(streams ...StreamI[T]) StreamI[T]
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@@ -72,12 +73,12 @@ func Generate[T any](generator func() func() (item T, ok bool)) stream[T] {
|
|||||||
return FromSlice(source)
|
return FromSlice(source)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromSlice create stream from slice.
|
// FromSlice creates stream from slice.
|
||||||
func FromSlice[T any](source []T) stream[T] {
|
func FromSlice[T any](source []T) stream[T] {
|
||||||
return stream[T]{source: source}
|
return stream[T]{source: source}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromChannel create stream from channel.
|
// FromChannel creates stream from channel.
|
||||||
func FromChannel[T any](source <-chan T) stream[T] {
|
func FromChannel[T any](source <-chan T) stream[T] {
|
||||||
s := make([]T, 0)
|
s := make([]T, 0)
|
||||||
|
|
||||||
@@ -88,7 +89,7 @@ func FromChannel[T any](source <-chan T) stream[T] {
|
|||||||
return FromSlice(s)
|
return FromSlice(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromRange create a number stream from start to end. both start and end are included. [start, end]
|
// FromRange creates a number stream from start to end. both start and end are included. [start, end]
|
||||||
func FromRange[T constraints.Integer | constraints.Float](start, end, step T) stream[T] {
|
func FromRange[T constraints.Integer | constraints.Float](start, end, step T) stream[T] {
|
||||||
if end < start {
|
if end < start {
|
||||||
panic("stream.FromRange: param start should be before param end")
|
panic("stream.FromRange: param start should be before param end")
|
||||||
@@ -106,6 +107,16 @@ func FromRange[T constraints.Integer | constraints.Float](start, end, step T) st
|
|||||||
return FromSlice(source)
|
return FromSlice(source)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Concat creates a lazily concatenated stream whose elements are all the elements of the first stream followed by all the elements of the second stream.
|
||||||
|
func Concat[T any](a, b stream[T]) stream[T] {
|
||||||
|
source := make([]T, 0)
|
||||||
|
|
||||||
|
source = append(source, a.source...)
|
||||||
|
source = append(source, b.source...)
|
||||||
|
|
||||||
|
return FromSlice(source)
|
||||||
|
}
|
||||||
|
|
||||||
// Distinct returns a stream that removes the duplicated items.
|
// Distinct returns a stream that removes the duplicated items.
|
||||||
func (s stream[T]) Distinct() stream[T] {
|
func (s stream[T]) Distinct() stream[T] {
|
||||||
source := make([]T, 0)
|
source := make([]T, 0)
|
||||||
@@ -167,7 +178,8 @@ func (s stream[T]) Peek(consumer func(item T)) stream[T] {
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip Returns a stream consisting of the remaining elements of this stream after discarding the first n elements of the stream. If this stream contains fewer than n elements then an empty stream will be returned.
|
// Skip returns a stream consisting of the remaining elements of this stream after discarding the first n elements of the stream.
|
||||||
|
// If this stream contains fewer than n elements then an empty stream will be returned.
|
||||||
func (s stream[T]) Skip(n int) stream[T] {
|
func (s stream[T]) Skip(n int) stream[T] {
|
||||||
if n <= 0 {
|
if n <= 0 {
|
||||||
return s
|
return s
|
||||||
@@ -180,8 +192,6 @@ func (s stream[T]) Skip(n int) stream[T] {
|
|||||||
return FromSlice(source)
|
return FromSlice(source)
|
||||||
}
|
}
|
||||||
|
|
||||||
// source = make([]T, l-n+1, l-n+1)
|
|
||||||
|
|
||||||
for i := n; i < l; i++ {
|
for i := n; i < l; i++ {
|
||||||
source = append(source, s.source[i])
|
source = append(source, s.source[i])
|
||||||
}
|
}
|
||||||
@@ -189,11 +199,165 @@ func (s stream[T]) Skip(n int) stream[T] {
|
|||||||
return FromSlice(source)
|
return FromSlice(source)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Limit returns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length.
|
||||||
|
func (s stream[T]) Limit(maxSize int) stream[T] {
|
||||||
|
if s.source == nil {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
if maxSize < 0 {
|
||||||
|
return FromSlice([]T{})
|
||||||
|
}
|
||||||
|
|
||||||
|
source := make([]T, 0, maxSize)
|
||||||
|
|
||||||
|
for i := 0; i < len(s.source) && i < maxSize; i++ {
|
||||||
|
source = append(source, s.source[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
return FromSlice(source)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllMatch returns whether all elements of this stream match the provided predicate.
|
||||||
|
func (s stream[T]) AllMatch(predicate func(item T) bool) bool {
|
||||||
|
for _, v := range s.source {
|
||||||
|
if !predicate(v) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// AnyMatch returns whether any elements of this stream match the provided predicate.
|
||||||
|
func (s stream[T]) AnyMatch(predicate func(item T) bool) bool {
|
||||||
|
for _, v := range s.source {
|
||||||
|
if predicate(v) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// NoneMatch returns whether no elements of this stream match the provided predicate.
|
||||||
|
func (s stream[T]) NoneMatch(predicate func(item T) bool) bool {
|
||||||
|
return !s.AnyMatch(predicate)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ForEach performs an action for each element of this stream.
|
||||||
|
func (s stream[T]) ForEach(action func(item T)) {
|
||||||
|
for _, v := range s.source {
|
||||||
|
action(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reduce performs a reduction on the elements of this stream, using an associative accumulation function, and returns an Optional describing the reduced value, if any.
|
||||||
|
func (s stream[T]) Reduce(init T, accumulator func(a, b T) T) T {
|
||||||
|
for _, v := range s.source {
|
||||||
|
init = accumulator(init, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return init
|
||||||
|
}
|
||||||
|
|
||||||
// Count returns the count of elements in the stream.
|
// Count returns the count of elements in the stream.
|
||||||
func (s stream[T]) Count() int {
|
func (s stream[T]) Count() int {
|
||||||
return len(s.source)
|
return len(s.source)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindFirst returns the first element of this stream and true, or zero value and false if the stream is empty.
|
||||||
|
func (s stream[T]) FindFirst() (T, bool) {
|
||||||
|
var result T
|
||||||
|
|
||||||
|
if s.source == nil || len(s.source) == 0 {
|
||||||
|
return result, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.source[0], true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reverse returns a stream whose elements are reverse order of given stream.
|
||||||
|
func (s stream[T]) Reverse() stream[T] {
|
||||||
|
l := len(s.source)
|
||||||
|
source := make([]T, l)
|
||||||
|
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
source[i] = s.source[l-1-i]
|
||||||
|
}
|
||||||
|
return FromSlice(source)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Range returns a stream whose elements are in the range from start(included) to end(excluded) original stream.
|
||||||
|
func (s stream[T]) Range(start, end int) stream[T] {
|
||||||
|
if start < 0 {
|
||||||
|
start = 0
|
||||||
|
}
|
||||||
|
if end < 0 {
|
||||||
|
end = 0
|
||||||
|
}
|
||||||
|
if start >= end {
|
||||||
|
return FromSlice([]T{})
|
||||||
|
}
|
||||||
|
|
||||||
|
source := make([]T, 0)
|
||||||
|
|
||||||
|
if end > len(s.source) {
|
||||||
|
end = len(s.source)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := start; i < end; i++ {
|
||||||
|
source = append(source, s.source[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
return FromSlice(source)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sorted returns a stream consisting of the elements of this stream, sorted according to the provided less function.
|
||||||
|
func (s stream[T]) Sorted(less func(a, b T) bool) stream[T] {
|
||||||
|
source := []T{}
|
||||||
|
source = append(source, s.source...)
|
||||||
|
|
||||||
|
slice.SortBy(source, less)
|
||||||
|
|
||||||
|
return FromSlice(source)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Max returns the maximum element of this stream according to the provided less function.
|
||||||
|
// less: a > b
|
||||||
|
func (s stream[T]) Max(less func(a, b T) bool) (T, bool) {
|
||||||
|
var max T
|
||||||
|
|
||||||
|
if len(s.source) == 0 {
|
||||||
|
return max, false
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, v := range s.source {
|
||||||
|
if less(v, max) || i == 0 {
|
||||||
|
max = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return max, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Min returns the minimum element of this stream according to the provided less function.
|
||||||
|
// less: a < b
|
||||||
|
func (s stream[T]) Min(less func(a, b T) bool) (T, bool) {
|
||||||
|
var min T
|
||||||
|
|
||||||
|
if len(s.source) == 0 {
|
||||||
|
return min, false
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, v := range s.source {
|
||||||
|
if less(v, min) || i == 0 {
|
||||||
|
min = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return min, true
|
||||||
|
}
|
||||||
|
|
||||||
// ToSlice return the elements in the stream.
|
// ToSlice return the elements in the stream.
|
||||||
func (s stream[T]) ToSlice() []T {
|
func (s stream[T]) ToSlice() []T {
|
||||||
return s.source
|
return s.source
|
||||||
|
|||||||
@@ -151,8 +151,188 @@ func TestStream_Skip(t *testing.T) {
|
|||||||
|
|
||||||
s1 := stream.Skip(-1)
|
s1 := stream.Skip(-1)
|
||||||
s2 := stream.Skip(0)
|
s2 := stream.Skip(0)
|
||||||
// s2 := stream.Skip(0)
|
|
||||||
|
|
||||||
assert.Equal([]int{1, 2, 3, 4, 5, 6}, s1.ToSlice())
|
assert.Equal([]int{1, 2, 3, 4, 5, 6}, s1.ToSlice())
|
||||||
assert.Equal([]int{1, 2, 3, 4, 5, 6}, s2.ToSlice())
|
assert.Equal([]int{1, 2, 3, 4, 5, 6}, s2.ToSlice())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestStream_Limit(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestStream_Limit")
|
||||||
|
|
||||||
|
stream := FromSlice([]int{1, 2, 3, 4, 5, 6})
|
||||||
|
|
||||||
|
s1 := stream.Limit(-1)
|
||||||
|
s2 := stream.Limit(0)
|
||||||
|
s3 := stream.Limit(1)
|
||||||
|
s4 := stream.Limit(6)
|
||||||
|
|
||||||
|
assert.Equal([]int{}, s1.ToSlice())
|
||||||
|
assert.Equal([]int{}, s2.ToSlice())
|
||||||
|
assert.Equal([]int{1}, s3.ToSlice())
|
||||||
|
assert.Equal([]int{1, 2, 3, 4, 5, 6}, s4.ToSlice())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStream_AllMatch(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestStream_AllMatch")
|
||||||
|
|
||||||
|
stream := FromSlice([]int{1, 2, 3, 4, 5, 6})
|
||||||
|
|
||||||
|
result1 := stream.AllMatch(func(item int) bool {
|
||||||
|
return item > 0
|
||||||
|
})
|
||||||
|
|
||||||
|
result2 := stream.AllMatch(func(item int) bool {
|
||||||
|
return item > 1
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(true, result1)
|
||||||
|
assert.Equal(false, result2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStream_AnyMatch(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestStream_AnyMatch")
|
||||||
|
|
||||||
|
stream := FromSlice([]int{1, 2, 3})
|
||||||
|
|
||||||
|
result1 := stream.AnyMatch(func(item int) bool {
|
||||||
|
return item > 3
|
||||||
|
})
|
||||||
|
|
||||||
|
result2 := stream.AnyMatch(func(item int) bool {
|
||||||
|
return item > 1
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(false, result1)
|
||||||
|
assert.Equal(true, result2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStream_NoneMatch(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestStream_NoneMatch")
|
||||||
|
|
||||||
|
stream := FromSlice([]int{1, 2, 3})
|
||||||
|
|
||||||
|
result1 := stream.NoneMatch(func(item int) bool {
|
||||||
|
return item > 3
|
||||||
|
})
|
||||||
|
|
||||||
|
result2 := stream.NoneMatch(func(item int) bool {
|
||||||
|
return item > 1
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(true, result1)
|
||||||
|
assert.Equal(false, result2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStream_ForEach(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestStream_ForEach")
|
||||||
|
|
||||||
|
stream := FromSlice([]int{1, 2, 3})
|
||||||
|
|
||||||
|
result := 0
|
||||||
|
stream.ForEach(func(item int) {
|
||||||
|
result += item
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(6, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStream_Reduce(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestStream_Reduce")
|
||||||
|
|
||||||
|
stream := FromSlice([]int{1, 2, 3})
|
||||||
|
|
||||||
|
result := stream.Reduce(0, func(a, b int) int {
|
||||||
|
return a + b
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(6, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStream_FindFirst(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestStream_FindFirst")
|
||||||
|
|
||||||
|
stream := FromSlice([]int{1, 2, 3})
|
||||||
|
|
||||||
|
result, ok := stream.FindFirst()
|
||||||
|
|
||||||
|
assert.Equal(1, result)
|
||||||
|
assert.Equal(true, ok)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStream_Reverse(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestStream_Reverse")
|
||||||
|
|
||||||
|
s := FromSlice([]int{1, 2, 3})
|
||||||
|
|
||||||
|
rs := s.Reverse()
|
||||||
|
|
||||||
|
assert.Equal([]int{3, 2, 1}, rs.ToSlice())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStream_Range(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestStream_Range")
|
||||||
|
|
||||||
|
s := FromSlice([]int{1, 2, 3})
|
||||||
|
|
||||||
|
s1 := s.Range(-1, 0)
|
||||||
|
assert.Equal([]int{}, s1.ToSlice())
|
||||||
|
|
||||||
|
s2 := s.Range(0, -1)
|
||||||
|
assert.Equal([]int{}, s2.ToSlice())
|
||||||
|
|
||||||
|
s3 := s.Range(0, 0)
|
||||||
|
assert.Equal([]int{}, s3.ToSlice())
|
||||||
|
|
||||||
|
s4 := s.Range(1, 1)
|
||||||
|
assert.Equal([]int{}, s4.ToSlice())
|
||||||
|
|
||||||
|
s5 := s.Range(0, 1)
|
||||||
|
assert.Equal([]int{1}, s5.ToSlice())
|
||||||
|
|
||||||
|
s6 := s.Range(0, 4)
|
||||||
|
assert.Equal([]int{1, 2, 3}, s6.ToSlice())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStream_Concat(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestStream_Concat")
|
||||||
|
|
||||||
|
s1 := FromSlice([]int{1, 2, 3})
|
||||||
|
s2 := FromSlice([]int{4, 5, 6})
|
||||||
|
|
||||||
|
s := Concat(s1, s2)
|
||||||
|
|
||||||
|
assert.Equal([]int{1, 2, 3, 4, 5, 6}, s.ToSlice())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStream_Sorted(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestStream_Sorted")
|
||||||
|
|
||||||
|
s := FromSlice([]int{4, 2, 1, 3})
|
||||||
|
|
||||||
|
s1 := s.Sorted(func(a, b int) bool { return a < b })
|
||||||
|
|
||||||
|
assert.Equal([]int{4, 2, 1, 3}, s.ToSlice())
|
||||||
|
assert.Equal([]int{1, 2, 3, 4}, s1.ToSlice())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStream_Max(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestStream_Max")
|
||||||
|
|
||||||
|
s := FromSlice([]int{4, 2, 1, 3})
|
||||||
|
|
||||||
|
max, ok := s.Max(func(a, b int) bool { return a > b })
|
||||||
|
|
||||||
|
assert.Equal(4, max)
|
||||||
|
assert.Equal(true, ok)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStream_Min(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestStream_Min")
|
||||||
|
|
||||||
|
s := FromSlice([]int{4, 2, 1, 3})
|
||||||
|
|
||||||
|
max, ok := s.Max(func(a, b int) bool { return a < b })
|
||||||
|
|
||||||
|
assert.Equal(1, max)
|
||||||
|
assert.Equal(true, ok)
|
||||||
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ var (
|
|||||||
chineseMobileMatcher *regexp.Regexp = regexp.MustCompile(`^1(?:3\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8\d|9\d)\d{8}$`)
|
chineseMobileMatcher *regexp.Regexp = regexp.MustCompile(`^1(?:3\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8\d|9\d)\d{8}$`)
|
||||||
chineseIdMatcher *regexp.Regexp = regexp.MustCompile(`^[1-9]\d{5}(18|19|20|21|22)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$`)
|
chineseIdMatcher *regexp.Regexp = regexp.MustCompile(`^[1-9]\d{5}(18|19|20|21|22)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$`)
|
||||||
chineseMatcher *regexp.Regexp = regexp.MustCompile("[\u4e00-\u9fa5]")
|
chineseMatcher *regexp.Regexp = regexp.MustCompile("[\u4e00-\u9fa5]")
|
||||||
chinesePhoneMatcher *regexp.Regexp = regexp.MustCompile(`\d{3}-\d{8}|\d{4}-\d{7}`)
|
chinesePhoneMatcher *regexp.Regexp = regexp.MustCompile(`\d{3}-\d{8}|\d{4}-\d{7}|\d{4}-\d{8}`)
|
||||||
creditCardMatcher *regexp.Regexp = regexp.MustCompile(`^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11}|6[27][0-9]{14})$`)
|
creditCardMatcher *regexp.Regexp = regexp.MustCompile(`^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11}|6[27][0-9]{14})$`)
|
||||||
base64Matcher *regexp.Regexp = regexp.MustCompile(`^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$`)
|
base64Matcher *regexp.Regexp = regexp.MustCompile(`^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$`)
|
||||||
)
|
)
|
||||||
@@ -281,6 +281,10 @@ func IsZeroValue(value any) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rv := reflect.ValueOf(value)
|
rv := reflect.ValueOf(value)
|
||||||
|
if rv.Kind() == reflect.Ptr {
|
||||||
|
rv = rv.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
if !rv.IsValid() {
|
if !rv.IsValid() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -208,6 +208,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(false, IsChinesePhone("123-87562"))
|
assert.Equal(false, IsChinesePhone("123-87562"))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
228
xerror/stack.go
Normal file
228
xerror/stack.go
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
// Copyright 2023 dudaodong@gmail.com. All rights reserved.
|
||||||
|
// Use of this source code is governed by MIT license
|
||||||
|
|
||||||
|
package xerror
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"path"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Stack contains function, file and line number info in the stack trace.
|
||||||
|
type Stack struct {
|
||||||
|
Func string `json:"func"`
|
||||||
|
File string `json:"file"`
|
||||||
|
Line int `json:"line"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stacks returns stack trace array generated by pkg/errors
|
||||||
|
func (e *XError) Stacks() []*Stack {
|
||||||
|
resp := make([]*Stack, len(*e.stack))
|
||||||
|
for i, st := range *e.stack {
|
||||||
|
f := frame(st)
|
||||||
|
resp[i] = &Stack{
|
||||||
|
Func: f.name(),
|
||||||
|
File: f.file(),
|
||||||
|
Line: f.line(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp
|
||||||
|
}
|
||||||
|
|
||||||
|
// StackTrace returns stack trace which is compatible with pkg/errors
|
||||||
|
func (e *XError) StackTrace() StackTrace {
|
||||||
|
return e.stack.StackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------
|
||||||
|
// Stacktrace part is implemented based on copy of https://github.com/pkg/errors
|
||||||
|
//
|
||||||
|
// Copyright (c) 2015, Dave Cheney <dave@cheney.net>
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright notice, this
|
||||||
|
// list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer in the documentation
|
||||||
|
// and/or other materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
type frame uintptr
|
||||||
|
type stack []uintptr
|
||||||
|
|
||||||
|
// StackTrace is array of frame. It's exported for compatibility with github.com/pkg/errors
|
||||||
|
type StackTrace []frame
|
||||||
|
|
||||||
|
// pc returns the program counter for this frame;
|
||||||
|
// multiple frames may have the same PC value.
|
||||||
|
func (f frame) pc() uintptr { return uintptr(f) - 1 }
|
||||||
|
|
||||||
|
// file returns the full path to the file that contains the
|
||||||
|
// function for this Frame's pc.
|
||||||
|
func (f frame) file() string {
|
||||||
|
fn := runtime.FuncForPC(f.pc())
|
||||||
|
if fn == nil {
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
file, _ := fn.FileLine(f.pc())
|
||||||
|
return file
|
||||||
|
}
|
||||||
|
|
||||||
|
// line returns the line number of source code of the
|
||||||
|
// function for this Frame's pc.
|
||||||
|
func (f frame) line() int {
|
||||||
|
fn := runtime.FuncForPC(f.pc())
|
||||||
|
if fn == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
_, line := fn.FileLine(f.pc())
|
||||||
|
return line
|
||||||
|
}
|
||||||
|
|
||||||
|
// name returns the name of this function, if known.
|
||||||
|
func (f frame) name() string {
|
||||||
|
fn := runtime.FuncForPC(f.pc())
|
||||||
|
if fn == nil {
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
return fn.Name()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format of frame formats the frame according to the fmt.Formatter interface.
|
||||||
|
//
|
||||||
|
// %s source file
|
||||||
|
// %d source line
|
||||||
|
// %n function name
|
||||||
|
// %v equivalent to %s:%d
|
||||||
|
//
|
||||||
|
// Format accepts flags that alter the printing of some verbs, as follows:
|
||||||
|
//
|
||||||
|
// %+s function name and path of source file relative to the compile time
|
||||||
|
// GOPATH separated by \n\t (<funcname>\n\t<path>)
|
||||||
|
// %+v equivalent to %+s:%d
|
||||||
|
func (f frame) Format(s fmt.State, verb rune) {
|
||||||
|
switch verb {
|
||||||
|
case 's':
|
||||||
|
switch {
|
||||||
|
case s.Flag('+'):
|
||||||
|
_, _ = io.WriteString(s, f.name())
|
||||||
|
_, _ = io.WriteString(s, "\n\t")
|
||||||
|
_, _ = io.WriteString(s, f.file())
|
||||||
|
default:
|
||||||
|
_, _ = io.WriteString(s, path.Base(f.file()))
|
||||||
|
}
|
||||||
|
case 'd':
|
||||||
|
_, _ = io.WriteString(s, strconv.Itoa(f.line()))
|
||||||
|
case 'n':
|
||||||
|
_, _ = io.WriteString(s, funcname(f.name()))
|
||||||
|
case 'v':
|
||||||
|
f.Format(s, 's')
|
||||||
|
_, _ = io.WriteString(s, ":")
|
||||||
|
f.Format(s, 'd')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalText formats a stacktrace Frame as a text string. The output is the
|
||||||
|
// same as that of fmt.Sprintf("%+v", f), but without newlines or tabs.
|
||||||
|
func (f frame) MarshalText() ([]byte, error) {
|
||||||
|
name := f.name()
|
||||||
|
if name == "unknown" {
|
||||||
|
return []byte(name), nil
|
||||||
|
}
|
||||||
|
return []byte(fmt.Sprintf("%s %s:%d", name, f.file(), f.line())), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format formats the stack of Frames according to the fmt.Formatter interface.
|
||||||
|
//
|
||||||
|
// %s lists source files for each Frame in the stack
|
||||||
|
// %v lists the source file and line number for each Frame in the stack
|
||||||
|
//
|
||||||
|
// Format accepts flags that alter the printing of some verbs, as follows:
|
||||||
|
//
|
||||||
|
// %+v Prints filename, function, and line number for each Frame in the stack.
|
||||||
|
func (st StackTrace) Format(s fmt.State, verb rune) {
|
||||||
|
switch verb {
|
||||||
|
case 'v':
|
||||||
|
switch {
|
||||||
|
case s.Flag('+'):
|
||||||
|
for _, f := range st {
|
||||||
|
_, _ = io.WriteString(s, "\n")
|
||||||
|
f.Format(s, verb)
|
||||||
|
}
|
||||||
|
case s.Flag('#'):
|
||||||
|
fmt.Fprintf(s, "%#v", []frame(st))
|
||||||
|
default:
|
||||||
|
st.formatSlice(s, verb)
|
||||||
|
}
|
||||||
|
case 's':
|
||||||
|
st.formatSlice(s, verb)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// formatSlice will format this StackTrace into the given buffer as a slice of
|
||||||
|
// Frame, only valid when called with '%s' or '%v'.
|
||||||
|
func (st StackTrace) formatSlice(s fmt.State, verb rune) {
|
||||||
|
_, _ = io.WriteString(s, "[")
|
||||||
|
for i, f := range st {
|
||||||
|
if i > 0 {
|
||||||
|
_, _ = io.WriteString(s, " ")
|
||||||
|
}
|
||||||
|
f.Format(s, verb)
|
||||||
|
}
|
||||||
|
_, _ = io.WriteString(s, "]")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack) Format(st fmt.State, verb rune) {
|
||||||
|
switch verb {
|
||||||
|
case 'v':
|
||||||
|
switch {
|
||||||
|
case st.Flag('+'):
|
||||||
|
for _, pc := range *s {
|
||||||
|
f := frame(pc)
|
||||||
|
fmt.Fprintf(st, "\n%+v", f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack) StackTrace() StackTrace {
|
||||||
|
frames := make([]frame, len(*s))
|
||||||
|
for i := 0; i < len(frames); i++ {
|
||||||
|
frames[i] = frame((*s)[i])
|
||||||
|
}
|
||||||
|
return frames
|
||||||
|
}
|
||||||
|
|
||||||
|
func callers() *stack {
|
||||||
|
const depth = 32
|
||||||
|
var pcs [depth]uintptr
|
||||||
|
n := runtime.Callers(4, pcs[:])
|
||||||
|
var st stack = pcs[0:n]
|
||||||
|
return &st
|
||||||
|
}
|
||||||
|
|
||||||
|
// funcname removes the path prefix component of a function's name reported by func.Name().
|
||||||
|
func funcname(name string) string {
|
||||||
|
i := strings.LastIndex(name, "/")
|
||||||
|
name = name[i+1:]
|
||||||
|
i = strings.Index(name, ".")
|
||||||
|
return name[i+1:]
|
||||||
|
}
|
||||||
196
xerror/xerror.go
196
xerror/xerror.go
@@ -4,10 +4,202 @@
|
|||||||
// Package xerror implements helpers for errors
|
// Package xerror implements helpers for errors
|
||||||
package xerror
|
package xerror
|
||||||
|
|
||||||
// Unwrap if err is nil then it returns a valid value
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/v2/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
// XError is to handle error related information.
|
||||||
|
type XError struct {
|
||||||
|
id string
|
||||||
|
message string
|
||||||
|
stack *stack
|
||||||
|
cause error
|
||||||
|
values map[string]any
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates a new XError with message
|
||||||
|
func New(format string, args ...any) *XError {
|
||||||
|
err := newXError()
|
||||||
|
err.message = fmt.Sprintf(format, args...)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap creates a new XError and add message.
|
||||||
|
func Wrap(cause error, message ...any) *XError {
|
||||||
|
err := newXError()
|
||||||
|
|
||||||
|
if len(message) > 0 {
|
||||||
|
var newMsgs []string
|
||||||
|
for _, m := range message {
|
||||||
|
newMsgs = append(newMsgs, fmt.Sprintf("%v", m))
|
||||||
|
}
|
||||||
|
err.message = strings.Join(newMsgs, " ")
|
||||||
|
}
|
||||||
|
|
||||||
|
err.cause = cause
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unwrap returns unwrapped XError from err by errors.As. If no XError, returns nil
|
||||||
|
func Unwrap(err error) *XError {
|
||||||
|
var e *XError
|
||||||
|
if errors.As(err, &e) {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newXError() *XError {
|
||||||
|
id, err := random.UUIdV4()
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &XError{
|
||||||
|
id: id,
|
||||||
|
stack: callers(),
|
||||||
|
values: make(map[string]any),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *XError) copy(dest *XError) {
|
||||||
|
dest.message = e.message
|
||||||
|
dest.id = e.id
|
||||||
|
dest.cause = e.cause
|
||||||
|
|
||||||
|
for k, v := range e.values {
|
||||||
|
dest.values[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error implements standard error interface.
|
||||||
|
func (e *XError) Error() string {
|
||||||
|
msg := e.message
|
||||||
|
cause := e.cause
|
||||||
|
|
||||||
|
if cause == nil {
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
msg = fmt.Sprintf("%s: %v", msg, cause.Error())
|
||||||
|
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format returns:
|
||||||
|
// - %v, %s, %q: formatted message
|
||||||
|
// - %+v: formatted message with stack trace
|
||||||
|
func (e *XError) Format(s fmt.State, verb rune) {
|
||||||
|
switch verb {
|
||||||
|
case 'v':
|
||||||
|
if s.Flag('+') {
|
||||||
|
_, _ = io.WriteString(s, e.Error())
|
||||||
|
e.stack.Format(s, verb)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
case 's':
|
||||||
|
_, _ = io.WriteString(s, e.Error())
|
||||||
|
case 'q':
|
||||||
|
fmt.Fprintf(s, "%q", e.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap creates a new XError and copy message and id to new one.
|
||||||
|
func (e *XError) Wrap(cause error) *XError {
|
||||||
|
err := newXError()
|
||||||
|
e.copy(err)
|
||||||
|
err.cause = cause
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unwrap compatible with github.com/pkg/errors
|
||||||
|
func (e *XError) Unwrap() error {
|
||||||
|
return e.cause
|
||||||
|
}
|
||||||
|
|
||||||
|
// With adds key and value related to the error object
|
||||||
|
func (e *XError) With(key string, value any) *XError {
|
||||||
|
e.values[key] = value
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is checks if target error is XError and Error.id of two errors are matched.
|
||||||
|
func (e *XError) Is(target error) bool {
|
||||||
|
var err *XError
|
||||||
|
|
||||||
|
if errors.As(target, &err) {
|
||||||
|
if e.id != "" && e.id == err.id {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return e == target
|
||||||
|
}
|
||||||
|
|
||||||
|
// Id sets id to check equality in XError.Is
|
||||||
|
func (e *XError) Id(id string) *XError {
|
||||||
|
e.id = id
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Values returns map of key and value that is set by With. All wrapped xerror.XError key and values will be merged.
|
||||||
|
// Key and values of wrapped error is overwritten by upper xerror.XError.
|
||||||
|
func (e *XError) Values() map[string]any {
|
||||||
|
var values map[string]any
|
||||||
|
|
||||||
|
if cause := e.Unwrap(); cause != nil {
|
||||||
|
if err, ok := cause.(*XError); ok {
|
||||||
|
values = err.Values()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if values == nil {
|
||||||
|
values = make(map[string]any)
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, value := range e.values {
|
||||||
|
values[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
|
||||||
|
type errInfo struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
Id string `json:"id"`
|
||||||
|
StackTrace []*Stack `json:"stacktrace"`
|
||||||
|
Cause error `json:"cause"`
|
||||||
|
Values map[string]any `json:"values"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Info returns information of xerror, which can be printed.
|
||||||
|
func (e *XError) Info() *errInfo {
|
||||||
|
errInfo := &errInfo{
|
||||||
|
Message: e.message,
|
||||||
|
Id: e.id,
|
||||||
|
StackTrace: e.Stacks(),
|
||||||
|
Cause: e.cause,
|
||||||
|
Values: make(map[string]any),
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range e.values {
|
||||||
|
errInfo.Values[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
return errInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
// TryUnwrap if err is nil then it returns a valid value
|
||||||
// If err is not nil, Unwrap panics with err.
|
// If err is not nil, Unwrap panics with err.
|
||||||
// Play: https://go.dev/play/p/w84d7Mb3Afk
|
// Play: https://go.dev/play/p/w84d7Mb3Afk
|
||||||
func Unwrap[T any](val T, err error) T {
|
func TryUnwrap[T any](val T, err error) T {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,144 @@
|
|||||||
package xerror
|
package xerror
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ExampleUnwrap() {
|
func ExampleNew() {
|
||||||
result1 := Unwrap(strconv.Atoi("42"))
|
err := New("error")
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// error
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleWrap() {
|
||||||
|
err := New("wrong password")
|
||||||
|
wrapErr := Wrap(err, "error")
|
||||||
|
|
||||||
|
fmt.Println(wrapErr.Error())
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// error: wrong password
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleXError_Wrap() {
|
||||||
|
err1 := New("error").With("level", "high")
|
||||||
|
err2 := err1.Wrap(errors.New("invalid username"))
|
||||||
|
|
||||||
|
fmt.Println(err2.Error())
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// error: invalid username
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleXError_Unwrap() {
|
||||||
|
err1 := New("error").With("level", "high")
|
||||||
|
err2 := err1.Wrap(errors.New("invalid username"))
|
||||||
|
|
||||||
|
err := err2.Unwrap()
|
||||||
|
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// invalid username
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleXError_StackTrace() {
|
||||||
|
err := New("error")
|
||||||
|
|
||||||
|
stacks := err.Stacks()
|
||||||
|
|
||||||
|
fmt.Println(stacks[0].Func)
|
||||||
|
fmt.Println(stacks[0].Line)
|
||||||
|
|
||||||
|
containFile := strings.Contains(stacks[0].File, "xerror_example_test.go")
|
||||||
|
fmt.Println(containFile)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// github.com/duke-git/lancet/v2/xerror.ExampleXError_StackTrace
|
||||||
|
// 52
|
||||||
|
// true
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleXError_With() {
|
||||||
|
err := New("error").With("level", "high")
|
||||||
|
|
||||||
|
errLevel := err.Values()["level"]
|
||||||
|
|
||||||
|
fmt.Println(errLevel)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// high
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleXError_Id() {
|
||||||
|
err1 := New("error").Id("e001")
|
||||||
|
err2 := New("error").Id("e001")
|
||||||
|
err3 := New("error").Id("e003")
|
||||||
|
|
||||||
|
equal := err1.Is(err2)
|
||||||
|
notEqual := err1.Is(err3)
|
||||||
|
|
||||||
|
fmt.Println(equal)
|
||||||
|
fmt.Println(notEqual)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleXError_Is() {
|
||||||
|
err1 := New("error").Id("e001")
|
||||||
|
err2 := New("error").Id("e001")
|
||||||
|
err3 := New("error").Id("e003")
|
||||||
|
|
||||||
|
equal := err1.Is(err2)
|
||||||
|
notEqual := err1.Is(err3)
|
||||||
|
|
||||||
|
fmt.Println(equal)
|
||||||
|
fmt.Println(notEqual)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleXError_Values() {
|
||||||
|
err := New("error").With("level", "high")
|
||||||
|
|
||||||
|
errLevel := err.Values()["level"]
|
||||||
|
|
||||||
|
fmt.Println(errLevel)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// high
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleXError_Info() {
|
||||||
|
cause := errors.New("error")
|
||||||
|
err := Wrap(cause, "invalid username").Id("e001").With("level", "high")
|
||||||
|
|
||||||
|
errInfo := err.Info()
|
||||||
|
|
||||||
|
fmt.Println(errInfo.Id)
|
||||||
|
fmt.Println(errInfo.Cause)
|
||||||
|
fmt.Println(errInfo.Values["level"])
|
||||||
|
fmt.Println(errInfo.Message)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// e001
|
||||||
|
// error
|
||||||
|
// high
|
||||||
|
// invalid username
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleTryUnwrap() {
|
||||||
|
result1 := TryUnwrap(strconv.Atoi("42"))
|
||||||
fmt.Println(result1)
|
fmt.Println(result1)
|
||||||
|
|
||||||
_, err := strconv.Atoi("4o2")
|
_, err := strconv.Atoi("4o2")
|
||||||
@@ -17,7 +148,7 @@ func ExampleUnwrap() {
|
|||||||
fmt.Println(result2)
|
fmt.Println(result2)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
Unwrap(strconv.Atoi("4o2"))
|
TryUnwrap(strconv.Atoi("4o2"))
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// 42
|
// 42
|
||||||
|
|||||||
@@ -1,19 +1,21 @@
|
|||||||
package xerror
|
package xerror
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/duke-git/lancet/v2/internal"
|
"github.com/duke-git/lancet/v2/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUnwrap(t *testing.T) {
|
func TestTryUnwrap(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestUnwrap")
|
assert := internal.NewAssert(t, "TestTryUnwrap")
|
||||||
assert.Equal(42, Unwrap(strconv.Atoi("42")))
|
assert.Equal(42, TryUnwrap(strconv.Atoi("42")))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUnwrapFail(t *testing.T) {
|
func TestTryUnwrapFail(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestUnwrapFail")
|
assert := internal.NewAssert(t, "TestTryUnwrapFail")
|
||||||
|
|
||||||
_, err := strconv.Atoi("4o2")
|
_, err := strconv.Atoi("4o2")
|
||||||
defer func() {
|
defer func() {
|
||||||
@@ -21,5 +23,85 @@ func TestUnwrapFail(t *testing.T) {
|
|||||||
assert.Equal(err.Error(), v.(*strconv.NumError).Error())
|
assert.Equal(err.Error(), v.(*strconv.NumError).Error())
|
||||||
}()
|
}()
|
||||||
|
|
||||||
Unwrap(strconv.Atoi("4o2"))
|
TryUnwrap(strconv.Atoi("4o2"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNew(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestNew")
|
||||||
|
|
||||||
|
err := New("error occurs")
|
||||||
|
assert.Equal("error occurs", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWrap(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestWrap")
|
||||||
|
|
||||||
|
err := New("wrong password")
|
||||||
|
wrapErr := Wrap(err, "error")
|
||||||
|
|
||||||
|
assert.Equal("error: wrong password", wrapErr.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestXError_Wrap(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestXError_Wrap")
|
||||||
|
|
||||||
|
err1 := New("error").With("level", "high")
|
||||||
|
err2 := err1.Wrap(errors.New("bad"))
|
||||||
|
|
||||||
|
assert.Equal("error: bad", err2.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestXError_Unwrap(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestXError_Unwrap")
|
||||||
|
|
||||||
|
err1 := New("error").With("level", "high")
|
||||||
|
|
||||||
|
err2 := err1.Wrap(errors.New("bad"))
|
||||||
|
|
||||||
|
err := err2.Unwrap()
|
||||||
|
|
||||||
|
assert.Equal("bad", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestXError_StackTrace(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestXError_StackTrace")
|
||||||
|
|
||||||
|
err := New("error")
|
||||||
|
|
||||||
|
stacks := err.Stacks()
|
||||||
|
|
||||||
|
assert.Equal(3, len(stacks))
|
||||||
|
assert.Equal("github.com/duke-git/lancet/v2/xerror.TestXError_StackTrace", stacks[0].Func)
|
||||||
|
assert.Equal(69, stacks[0].Line)
|
||||||
|
assert.Equal(true, strings.Contains(stacks[0].File, "xerror_test.go"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestXError_With_Id_Is_Values(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestXError_With_Id_Is_Values")
|
||||||
|
|
||||||
|
baseErr := New("baseError")
|
||||||
|
err1 := New("error1").Id("e001").With("level", "high")
|
||||||
|
err2 := New("error2").Id("e002").With("level", "low")
|
||||||
|
|
||||||
|
err := err1.Wrap(baseErr).With("v", "1.0")
|
||||||
|
|
||||||
|
assert.Equal(true, errors.Is(err, baseErr))
|
||||||
|
assert.NotEqual(err, err1)
|
||||||
|
assert.IsNotNil(err.Values()["v"])
|
||||||
|
assert.IsNil(err1.Values()["v"])
|
||||||
|
|
||||||
|
assert.Equal(false, errors.Is(err, err2))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestXError_Info(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestXError_Info")
|
||||||
|
|
||||||
|
cause := errors.New("error")
|
||||||
|
err := Wrap(cause, "invalid username").Id("e001").With("level", "high")
|
||||||
|
|
||||||
|
errInfo := err.Info()
|
||||||
|
assert.Equal("invalid username", errInfo.Message)
|
||||||
|
assert.Equal("e001", errInfo.Id)
|
||||||
|
assert.Equal(cause, errInfo.Cause)
|
||||||
|
assert.Equal("high", errInfo.Values["level"])
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user