mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-20 12:22:29 +08:00
Compare commits
18 Commits
v2.2.3
...
a0431d9435
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a0431d9435 | ||
|
|
0456b65cc7 | ||
|
|
989b4dd791 | ||
|
|
a76b02fbba | ||
|
|
2d7747738a | ||
|
|
fe0cb04137 | ||
|
|
fe0264f628 | ||
|
|
65396cee32 | ||
|
|
544702b460 | ||
|
|
d8936cdcb5 | ||
|
|
d4b97d6b20 | ||
|
|
5caa14c838 | ||
|
|
0d0848ac67 | ||
|
|
d5334f892f | ||
|
|
36ef5b3bd3 | ||
|
|
6f48b00c88 | ||
|
|
7b744c299e | ||
|
|
154ec56780 |
51
README.md
51
README.md
@@ -397,6 +397,9 @@ import "github.com/duke-git/lancet/v2/cryptor"
|
||||
- **<big>HmacSha512</big>** : return the hmac hash of string use sha512.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#HmacSha512)]
|
||||
[[play](https://go.dev/play/p/59Od6m4A0Ud)]
|
||||
- **<big>Md5Byte</big>** : return the md5 string of byte slice.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Md5Byte)]
|
||||
[[play](https://go.dev/play/p/suraalH8lyC)]
|
||||
- **<big>Md5String</big>** : return the md5 value of string.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Md5String)]
|
||||
[[play](https://go.dev/play/p/1bLcVetbTOI)]
|
||||
@@ -486,6 +489,12 @@ import "github.com/duke-git/lancet/v2/datetime"
|
||||
- **<big>GetNowDateTime</big>** : return format yyyy-mm-dd hh-mm-ss of current datetime.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetNowDateTime)]
|
||||
[[play](https://go.dev/play/p/pI4AqngD0al)]
|
||||
- **<big>GetTodayStartTime</big>** : return the start time of today, format: yyyy-mm-dd 00:00:00.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetTodayStartTime)]
|
||||
[[play](https://go.dev/play/p/84siyYF7t99)]
|
||||
- **<big>GetTodayEndTime</big>** : return the end time of today, format: yyyy-mm-dd 23:59:59.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetTodayEndTime)]
|
||||
[[play](https://go.dev/play/p/jjrLnfoqgn3)]
|
||||
- **<big>GetZeroHourTimestamp</big>** : return timestamp of zero hour (timestamp of 00:00).
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetZeroHourTimestamp)]
|
||||
[[play](https://go.dev/play/p/QmL2oIaGE3q)]
|
||||
@@ -959,6 +968,12 @@ import "github.com/duke-git/lancet/v2/pointer"
|
||||
- **<big>Unwrap</big>** : return the value from the pointer.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/pointer.md#Unwrap)]
|
||||
[[play](https://go.dev/play/p/cgeu3g7cjWb)]
|
||||
- **<big>UnwarpOr</big>** : UnwarpOr returns the value from the pointer or fallback if the pointer is nil.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/pointer.md#UnwrapOr)]
|
||||
[[play](https://go.dev/play/p/mmNaLC38W8C)]
|
||||
- **<big>UnwarpOrDefault</big>** : UnwarpOrDefault returns the value from the pointer or the default value if the pointer is nil.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/pointer.md#UnwrapOrDefault)]
|
||||
[[play](https://go.dev/play/p/ZnGIHf8_o4E)]
|
||||
|
||||
<h3 id="Random"> 16. Random package implements some basic functions to generate random int and string. <a href="#index">index</a></h3>
|
||||
|
||||
@@ -1517,76 +1532,112 @@ import "github.com/duke-git/lancet/v2/tuple"
|
||||
|
||||
- **<big>Tuple2</big>** : represents a 2 elemnets tuple.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Tuple2)]
|
||||
[[play](https://go.dev/play/p/3sHVqBQpLYN)]
|
||||
- **<big>Tuple2_Unbox</big>** : returns values in Tuple2.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Tuple2_Unbox)]
|
||||
[[play](https://go.dev/play/p/0fD1qfCVwjm)]
|
||||
- **<big>Zip2</big>** : create a slice of Tuple2, whose elements are correspond to the given slice elements.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Zip2)]
|
||||
[[play](https://go.dev/play/p/4ncWJJ77Xio)]
|
||||
- **<big>Unzip2</big>** : create a group of slice from a slice of Tuple2.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Unzip2)]
|
||||
[[play](https://go.dev/play/p/KBecr60feXb)]
|
||||
- **<big>Tuple3</big>** : represents a 3 elemnets tuple.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Tuple3)]
|
||||
[[play](https://go.dev/play/p/FtH2sdCLlCf)]
|
||||
- **<big>Tuple3_Unbox</big>** : returns values in Tuple3.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Tuple3_Unbox)]
|
||||
[[play](https://go.dev/play/p/YojLy-id1BS)]
|
||||
- **<big>Zip3</big>** : create a slice of Tuple3, whose elements are correspond to the given slice elements.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Zip3)]
|
||||
[[play](https://go.dev/play/p/97NgmsTILfu)]
|
||||
- **<big>Unzip3</big>** : create a group of slice from a slice of Tuple3.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Unzip3)]
|
||||
[[play](https://go.dev/play/p/bba4cpAa7KO)]
|
||||
- **<big>Tuple4</big>** : represents a 4 elemnets tuple.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Tuple4)]
|
||||
[[play](https://go.dev/play/p/D2EqDz096tk)]
|
||||
- **<big>Tuple4_Unbox</big>** : returns values in Tuple4.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Tuple4_Unbox)]
|
||||
[[play](https://go.dev/play/p/ACj9YuACGgW)]
|
||||
- **<big>Zip4</big>** : create a slice of Tuple4, whose elements are correspond to the given slice elements.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Zip4)]
|
||||
[[play](https://go.dev/play/p/PEmTYVK5hL4)]
|
||||
- **<big>Unzip4</big>** : create a group of slice from a slice of Tuple4.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Unzip4)]
|
||||
[[play](https://go.dev/play/p/rb8z4gyYSRN)]
|
||||
- **<big>Tuple5</big>** : represents a 5 elemnets tuple.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Tuple5)]
|
||||
[[play](https://go.dev/play/p/2WndmVxPg-r)]
|
||||
- **<big>Tuple5_Unbox</big>** : returns values in Tuple4.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Tuple5_Unbox)]
|
||||
[[play](https://go.dev/play/p/GyIyZHjCvoS)]
|
||||
- **<big>Zip5</big>** : create a slice of Tuple5, whose elements are correspond to the given slice elements.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Zip5)]
|
||||
[[play](https://go.dev/play/p/fCAAJLMfBIP)]
|
||||
- **<big>Unzip5</big>** : create a group of slice from a slice of Tuple5.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Unzip5)]
|
||||
[[play](https://go.dev/play/p/gyl6vKfhqPb)]
|
||||
- **<big>Tuple6</big>** : represents a 6 elemnets tuple.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Tuple6)]
|
||||
[[play](https://go.dev/play/p/VjqcCwEJZbs)]
|
||||
- **<big>Tuple6_Unbox</big>** : returns values in Tuple6.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Tuple6_Unbox)]
|
||||
[[play](https://go.dev/play/p/FjIHV7lpxmW)]
|
||||
- **<big>Zip6</big>** : create a slice of Tuple6, whose elements are correspond to the given slice elements.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Zip6)]
|
||||
[[play](https://go.dev/play/p/oWPrnUYuFHo)]
|
||||
- **<big>Unzip6</big>** : create a group of slice from a slice of Tuple6.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Unzip6)]
|
||||
[[play](https://go.dev/play/p/l41XFqCyh5E)]
|
||||
- **<big>Tuple7</big>** : represents a 7 elemnets tuple.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Tuple7)]
|
||||
[[play](https://go.dev/play/p/dzAgv_Ezub9)]
|
||||
- **<big>Tuple7_Unbox</big>** : returns values in Tuple7.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Tuple7_Unbox)]
|
||||
[[play](https://go.dev/play/p/R9I8qeDk0zs)]
|
||||
- **<big>Zip7</big>** : create a slice of Tuple7, whose elements are correspond to the given slice elements.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Zip7)]
|
||||
[[play](https://go.dev/play/p/WUJuo897Egf)]
|
||||
- **<big>Unzip7</big>** : create a group of slice from a slice of Tuple7.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Unzip7)]
|
||||
[[play](https://go.dev/play/p/hws_P1Fr2j3)]
|
||||
- **<big>Tuple8</big>** : represents a 8 elemnets tuple.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Tuple8)]
|
||||
[[play](https://go.dev/play/p/YA9S0rz3dRz)]
|
||||
- **<big>Tuple8_Unbox</big>** : returns values in Tuple8.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Tuple8_Unbox)]
|
||||
[[play](https://go.dev/play/p/PRxLBBb4SMl)]
|
||||
- **<big>Zip8</big>** : create a slice of Tuple8, whose elements are correspond to the given slice elements.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Zip8)]
|
||||
[[play](https://go.dev/play/p/8V9jWkuJfaQ)]
|
||||
- **<big>Unzip8</big>** : create a group of slice from a slice of Tuple8.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Unzip8)]
|
||||
[[play](https://go.dev/play/p/1SndOwGsZB4)]
|
||||
- **<big>Tuple9</big>** : represents a 9 elemnets tuple.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Tuple9)]
|
||||
[[play](https://go.dev/play/p/yS2NGGtZpQr)]
|
||||
- **<big>Tuple9_Unbox</big>** : returns values in Tuple9.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Tuple9_Unbox)]
|
||||
[[play](https://go.dev/play/p/oFJFGTAuOa8)]
|
||||
- **<big>Zip9</big>** : create a slice of Tuple9, whose elements are correspond to the given slice elements.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Zip9)]
|
||||
[[play](https://go.dev/play/p/cgsL15QYnfz)]
|
||||
- **<big>Unzip9</big>** : create a group of slice from a slice of Tuple9.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Unzip9)]
|
||||
[[play](https://go.dev/play/p/91-BU_KURSA)]
|
||||
- **<big>Tuple10</big>** : represents a 10 elemnets tuple.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Tuple10)]
|
||||
[[play](https://go.dev/play/p/799qqZg0hUv)]
|
||||
- **<big>Tuple10_Unbox</big>** : returns values in Tuple10.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Tuple10_Unbox)]
|
||||
[[play](https://go.dev/play/p/qfyx3x_X0Cu)]
|
||||
- **<big>Zip10</big>** : create a slice of Tuple10, whose elements are correspond to the given slice elements.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Zip10)]
|
||||
[[play](https://go.dev/play/p/YSR-2cXnrY4)]
|
||||
- **<big>Unzip10</big>** : create a group of slice from a slice of Tuple10.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple.md#Unzip10)]
|
||||
[[play](https://go.dev/play/p/-taQB6Wfre_z)]
|
||||
|
||||
<h3 id="Validator"> 24. Validator package contains some functions for data validation. <a href="#index">index</a></h3>
|
||||
|
||||
|
||||
@@ -396,6 +396,9 @@ import "github.com/duke-git/lancet/v2/cryptor"
|
||||
- **<big>HmacSha512</big>** : 返回字符串 sha256 hmac 值。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#HmacSha512)]
|
||||
[[play](https://go.dev/play/p/59Od6m4A0Ud)]
|
||||
- **<big>Md5Byte</big>** : 返回byte slice的md5值.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Md5Byte)]
|
||||
[[play](https://go.dev/play/p/suraalH8lyC)]
|
||||
- **<big>Md5String</big>** : 返回字符串 md5 值。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Md5String)]
|
||||
[[play](https://go.dev/play/p/1bLcVetbTOI)]
|
||||
@@ -485,6 +488,12 @@ import "github.com/duke-git/lancet/v2/datetime"
|
||||
- **<big>GetNowDateTime</big>** : 获取当时日期和时间,返回格式:yyyy-mm-dd hh:mm:ss。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetNowDateTime)]
|
||||
[[play](https://go.dev/play/p/pI4AqngD0al)]
|
||||
- **<big>GetTodayStartTime</big>** : 返回当天开始时间, 格式: yyyy-mm-dd 00:00:00。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetTodayStartTime)]
|
||||
[[play](https://go.dev/play/p/84siyYF7t99)]
|
||||
- **<big>GetTodayEndTime</big>** : 返回当天结束时间,格式: yyyy-mm-dd 23:59:59。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetTodayEndTime)]
|
||||
[[play](https://go.dev/play/p/jjrLnfoqgn3)]
|
||||
- **<big>GetZeroHourTimestamp</big>** : 获取零时时间戳(timestamp of 00:00)。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetZeroHourTimestamp)]
|
||||
[[play](https://go.dev/play/p/QmL2oIaGE3q)]
|
||||
@@ -1522,76 +1531,113 @@ import "github.com/duke-git/lancet/v2/tuple"
|
||||
|
||||
- **<big>Tuple2</big>** : 2 元元组
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Tuple2)]
|
||||
[[play](https://go.dev/play/p/3sHVqBQpLYN)]
|
||||
- **<big>Tuple2_Unbox</big>** : 返回 2 元元组的字段值。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Tuple2_Unbox)]
|
||||
[[play](https://go.dev/play/p/0fD1qfCVwjm)]
|
||||
- **<big>Zip2</big>** : 创建一个 Tuple2 元组切片, 其中元组的元素和传入切片元素相对应。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Zip2)]
|
||||
[[play](https://go.dev/play/p/4ncWJJ77Xio)]
|
||||
- **<big>Unzip2</big>** : 根据传入的Tuple2切片,创建一组和Tuple2元素相对应的切片。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Unzip2)]
|
||||
[[play](https://go.dev/play/p/KBecr60feXb)]
|
||||
- **<big>Tuple3</big>** : 3 元元组
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Tuple3)]
|
||||
[[play](https://go.dev/play/p/FtH2sdCLlCf)]
|
||||
- **<big>Tuple3_Unbox</big>** : 返回 3 元元组的字段值。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Tuple3_Unbox)]
|
||||
[[play](https://go.dev/play/p/YojLy-id1BS)]
|
||||
- **<big>Zip3</big>** : 创建一个 Tuple3 元组切片, 其中元组的元素和传入切片元素相对应。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Zip3)]
|
||||
[[play](https://go.dev/play/p/97NgmsTILfu)]
|
||||
- **<big>Unzip3</big>** : 根据传入的Tuple3切片,创建一组和Tuple3元素相对应的切片。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Unzip3)]
|
||||
[[play](https://go.dev/play/p/bba4cpAa7KO)]
|
||||
- **<big>Tuple4</big>** : 4 元元组
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Tuple4)]
|
||||
[[play](https://go.dev/play/p/D2EqDz096tk)]
|
||||
- **<big>Tuple4_Unbox</big>** : 返回 4 元元组的字段值。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Tuple4_Unbox)]
|
||||
[[play](https://go.dev/play/p/ACj9YuACGgW)]
|
||||
- **<big>Zip4</big>** : 创建一个 Tuple4 元组切片, 其中元组的元素和传入切片元素相对应。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Zip4)]
|
||||
[[play](https://go.dev/play/p/PEmTYVK5hL4)]
|
||||
- **<big>Unzip4</big>** : 根据传入的Tuple4切片,创建一组和Tuple4元素相对应的切片。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Unzip4)]
|
||||
[[play](https://go.dev/play/p/rb8z4gyYSRN)]
|
||||
- **<big>Tuple5</big>** : 5 元元组
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Tuple5)]
|
||||
[[play](https://go.dev/play/p/2WndmVxPg-r)]
|
||||
- **<big>Tuple5_Unbox</big>** : 返回 5 元元组的字段值。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Tuple5_Unbox)]
|
||||
[[play](https://go.dev/play/p/GyIyZHjCvoS)]
|
||||
- **<big>Zip5</big>** : 创建一个 Tuple5 元组切片, 其中元组的元素和传入切片元素相对应。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Zip5)]
|
||||
[[play](https://go.dev/play/p/fCAAJLMfBIP)]
|
||||
- **<big>Unzip5</big>** : 根据传入的Tuple5切片,创建一组和Tuple5元素相对应的切片。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Unzip5)]
|
||||
[[play](https://go.dev/play/p/gyl6vKfhqPb)]
|
||||
- **<big>Tuple6</big>** : 6 元元组
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Tuple6)]
|
||||
[[play](https://go.dev/play/p/VjqcCwEJZbs)]
|
||||
- **<big>Tuple6_Unbox</big>** : 返回 6 元元组的字段值。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Tuple6_Unbox)]
|
||||
[[play](https://go.dev/play/p/FjIHV7lpxmW)]
|
||||
- **<big>Zip6</big>** : 创建一个 Tuple6 元组切片, 其中元组的元素和传入切片元素相对应。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Zip6)]
|
||||
[[play](https://go.dev/play/p/oWPrnUYuFHo)]
|
||||
- **<big>Unzip6</big>** : 根据传入的Tuple6切片,创建一组和Tuple6元素相对应的切片。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Unzip6)]
|
||||
[[play](https://go.dev/play/p/l41XFqCyh5E)]
|
||||
- **<big>Tuple7</big>** : 7 元元组
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Tuple7)]
|
||||
[[play](https://go.dev/play/p/dzAgv_Ezub9)]
|
||||
- **<big>Tuple7_Unbox</big>** : 返回 7 元元组的字段值。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Tuple7_Unbox)]
|
||||
[[play](https://go.dev/play/p/R9I8qeDk0zs)]
|
||||
- **<big>Zip7</big>** : 创建一个 Tuple7 元组切片, 其中元组的元素和传入切片元素相对应。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Zip7)]
|
||||
[[play](https://go.dev/play/p/WUJuo897Egf)]
|
||||
- **<big>Unzip7</big>** : 根据传入的Tuple7切片,创建一组和Tuple7元素相对应的切片。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Unzip7)]
|
||||
[[play](https://go.dev/play/p/hws_P1Fr2j3)]
|
||||
- **<big>Tuple8</big>** : 8 元元组
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Tuple8)]
|
||||
[[play](https://go.dev/play/p/YA9S0rz3dRz)]
|
||||
- **<big>Tuple8_Unbox</big>** : 返回 8 元元组的字段值。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Tuple8_Unbox)]
|
||||
[[play](https://go.dev/play/p/PRxLBBb4SMl)]
|
||||
- **<big>Zip8</big>** : 创建一个 Tuple8 元组切片, 其中元组的元素和传入切片元素相对应。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Zip8)]
|
||||
[[play](https://go.dev/play/p/8V9jWkuJfaQ)]
|
||||
- **<big>Unzip8</big>** : 根据传入的Tuple8切片,创建一组和Tuple8元素相对应的切片。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Unzip8)]
|
||||
[[play](https://go.dev/play/p/1SndOwGsZB4)]
|
||||
- **<big>Tuple9</big>** : 9 元元组
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Tuple9)]
|
||||
[[play](https://go.dev/play/p/yS2NGGtZpQr)]
|
||||
- **<big>Tuple9_Unbox</big>** : 返回 9 元元组的字段值。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Tuple9_Unbox)]
|
||||
[[play](https://go.dev/play/p/oFJFGTAuOa8)]
|
||||
- **<big>Zip9</big>** : 创建一个 Tuple9 元组切片, 其中元组的元素和传入切片元素相对应。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Zip9)]
|
||||
[[play](https://go.dev/play/p/cgsL15QYnfz)]
|
||||
- **<big>Unzip9</big>** : 根据传入的Tuple9切片,创建一组和Tuple9元素相对应的切片。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Unzip9)]
|
||||
[[play](https://go.dev/play/p/91-BU_KURSA)]
|
||||
- **<big>Tuple10</big>** : 10 元元组
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Tuple10)]
|
||||
[[play](https://go.dev/play/p/799qqZg0hUv)]
|
||||
- **<big>Tuple10_Unbox</big>** : 返回 10 元元组的字段值。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Tuple10_Unbox)]
|
||||
[[play](https://go.dev/play/p/qfyx3x_X0Cu)]
|
||||
- **<big>Zip10</big>** : 创建一个 Tuple10 元组切片, 其中元组的元素和传入切片元素相对应。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Zip10)]
|
||||
[[play](https://go.dev/play/p/YSR-2cXnrY4)]
|
||||
- **<big>Unzip10</big>** : 根据传入的Tuple10切片,创建一组和Tuple10元素相对应的切片。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/tuple_zh-CN.md#Unzip10)]
|
||||
[[play](https://go.dev/play/p/-taQB6Wfre_z)]
|
||||
|
||||
|
||||
<h3 id="Validator"> 24. validator 验证器包,包含常用字符串格式验证函数。 <a href="#index">回到目录</a></h3>
|
||||
|
||||
|
||||
@@ -40,14 +40,30 @@ func Md5String(s string) string {
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
// Md5String return the md5 string of byte slice.
|
||||
// Play: todo
|
||||
// Md5String return the md5 value of string.
|
||||
// Play: https://go.dev/play/p/Lx4gH7Vdr5_y
|
||||
func Md5StringWithBase64(s string) string {
|
||||
h := md5.New()
|
||||
h.Write([]byte(s))
|
||||
return base64.StdEncoding.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
// Md5Byte return the md5 string of byte slice.
|
||||
// Play: https://go.dev/play/p/suraalH8lyC
|
||||
func Md5Byte(data []byte) string {
|
||||
h := md5.New()
|
||||
h.Write(data)
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
// Md5Byte return the md5 string of byte slice.
|
||||
// Play: https://go.dev/play/p/CkN9hYKGeAy
|
||||
func Md5ByteWithBase64(data []byte) string {
|
||||
h := md5.New()
|
||||
h.Write(data)
|
||||
return base64.StdEncoding.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
// Md5File return the md5 value of file.
|
||||
func Md5File(filename string) (string, error) {
|
||||
if fileInfo, err := os.Stat(filename); err != nil {
|
||||
@@ -96,6 +112,14 @@ func HmacSha1(data, key string) string {
|
||||
return hex.EncodeToString(h.Sum([]byte("")))
|
||||
}
|
||||
|
||||
// HmacSha1 return the hmac hash of string use sha1.
|
||||
// Play: https://go.dev/play/p/47JmmGrnF7B
|
||||
func HmacSha1WithBase64(data, key string) string {
|
||||
h := hmac.New(sha1.New, []byte(key))
|
||||
h.Write([]byte(data))
|
||||
return base64.StdEncoding.EncodeToString(h.Sum([]byte("")))
|
||||
}
|
||||
|
||||
// HmacSha256 return the hmac hash of string use sha256.
|
||||
// Play: https://go.dev/play/p/HhpwXxFhhC0
|
||||
func HmacSha256(data, key string) string {
|
||||
@@ -104,6 +128,14 @@ func HmacSha256(data, key string) string {
|
||||
return hex.EncodeToString(h.Sum([]byte("")))
|
||||
}
|
||||
|
||||
// HmacSha256 return the hmac hash of string use sha256 with base64.
|
||||
// Play: https://go.dev/play/p/EKbkUvPTLwO
|
||||
func HmacSha256WithBase64(data, key string) string {
|
||||
h := hmac.New(sha256.New, []byte(key))
|
||||
h.Write([]byte(data))
|
||||
return base64.StdEncoding.EncodeToString(h.Sum([]byte("")))
|
||||
}
|
||||
|
||||
// HmacSha512 return the hmac hash of string use sha512.
|
||||
// Play: https://go.dev/play/p/59Od6m4A0Ud
|
||||
func HmacSha512(data, key string) string {
|
||||
@@ -112,6 +144,14 @@ func HmacSha512(data, key string) string {
|
||||
return hex.EncodeToString(h.Sum([]byte("")))
|
||||
}
|
||||
|
||||
// HmacSha512 return the hmac hash of string use sha512 with base64..
|
||||
// Play: https://go.dev/play/p/61wBBOKO-GH
|
||||
func HmacSha512WithBase64(data, key string) string {
|
||||
h := hmac.New(sha512.New, []byte(key))
|
||||
h.Write([]byte(data))
|
||||
return base64.StdEncoding.EncodeToString(h.Sum([]byte("")))
|
||||
}
|
||||
|
||||
// Sha1 return the sha1 value (SHA-1 hash algorithm) of string.
|
||||
// Play: https://go.dev/play/p/_m_uoD1deMT
|
||||
func Sha1(data string) string {
|
||||
@@ -120,6 +160,14 @@ func Sha1(data string) string {
|
||||
return hex.EncodeToString(sha1.Sum([]byte("")))
|
||||
}
|
||||
|
||||
// Sha1 return the sha1 value (SHA-1 hash algorithm) of base64 string.
|
||||
// Play: todo
|
||||
func Sha1WithBase64(data string) string {
|
||||
sha1 := sha1.New()
|
||||
sha1.Write([]byte(data))
|
||||
return base64.StdEncoding.EncodeToString(sha1.Sum([]byte("")))
|
||||
}
|
||||
|
||||
// Sha256 return the sha256 value (SHA256 hash algorithm) of string.
|
||||
// Play: https://go.dev/play/p/tU9tfBMIAr1
|
||||
func Sha256(data string) string {
|
||||
@@ -128,6 +176,14 @@ func Sha256(data string) string {
|
||||
return hex.EncodeToString(sha256.Sum([]byte("")))
|
||||
}
|
||||
|
||||
// Sha256 return the sha256 value (SHA256 hash algorithm) of base64 string.
|
||||
// Play: https://go.dev/play/p/85IXJHIal1k
|
||||
func Sha256WithBase64(data string) string {
|
||||
sha256 := sha256.New()
|
||||
sha256.Write([]byte(data))
|
||||
return base64.StdEncoding.EncodeToString(sha256.Sum([]byte("")))
|
||||
}
|
||||
|
||||
// Sha512 return the sha512 value (SHA512 hash algorithm) of string.
|
||||
// Play: https://go.dev/play/p/3WsvLYZxsHa
|
||||
func Sha512(data string) string {
|
||||
@@ -135,3 +191,11 @@ func Sha512(data string) string {
|
||||
sha512.Write([]byte(data))
|
||||
return hex.EncodeToString(sha512.Sum([]byte("")))
|
||||
}
|
||||
|
||||
// Sha512 return the sha512 value (SHA512 hash algorithm) of base64 string.
|
||||
// Play: https://go.dev/play/p/q_fY2rA-k5I
|
||||
func Sha512WithBase64(data string) string {
|
||||
sha512 := sha512.New()
|
||||
sha512.Write([]byte(data))
|
||||
return base64.StdEncoding.EncodeToString(sha512.Sum([]byte("")))
|
||||
}
|
||||
|
||||
@@ -27,6 +27,13 @@ func TestMd5String(t *testing.T) {
|
||||
assert.Equal("5d41402abc4b2a76b9719d911017c592", Md5String("hello"))
|
||||
}
|
||||
|
||||
func TestMd5StringWithBase64(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := internal.NewAssert(t, "TestMd5StringWithBase64")
|
||||
assert.Equal("XUFAKrxLKna5cZ2REBfFkg==", Md5StringWithBase64("hello"))
|
||||
}
|
||||
|
||||
func TestMd5Byte(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -35,6 +42,13 @@ func TestMd5Byte(t *testing.T) {
|
||||
assert.Equal("0cc175b9c0f1b6a831c399e269772661", Md5Byte(data))
|
||||
}
|
||||
|
||||
func TestMd5ByteWithBase64(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := internal.NewAssert(t, "TestMd5ByteWithBase64")
|
||||
assert.Equal("XUFAKrxLKna5cZ2REBfFkg==", Md5ByteWithBase64([]byte("hello")))
|
||||
}
|
||||
|
||||
func TestMd5File(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -63,18 +77,42 @@ func TestHmacSha1(t *testing.T) {
|
||||
assert.Equal(expected, hmacSha1)
|
||||
}
|
||||
|
||||
func TestHmacSha1WithBase64(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := "hello"
|
||||
key := "12345"
|
||||
hmacSha1 := HmacSha1WithBase64(s, key)
|
||||
expected := "XGqdsMzLkuNu0DI/0Jt/k23prOA="
|
||||
|
||||
assert := internal.NewAssert(t, "TestHmacSha1")
|
||||
assert.Equal(expected, hmacSha1)
|
||||
}
|
||||
|
||||
func TestHmacSha256(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := "hello world"
|
||||
str := "hello world"
|
||||
key := "12345"
|
||||
hmacSha256 := HmacSha256(s, key)
|
||||
hmacSha256 := HmacSha256(str, key)
|
||||
expected := "9dce2609f2d67d41f74c7f9efc8ccd44370d41ad2de52982627588dfe7289ab8"
|
||||
|
||||
assert := internal.NewAssert(t, "TestHmacSha256")
|
||||
assert.Equal(expected, hmacSha256)
|
||||
}
|
||||
|
||||
func TestHmacSha256WithBase64(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
str := "hello"
|
||||
key := "12345"
|
||||
hms := HmacSha256WithBase64(str, key)
|
||||
expected := "MVu5PE6YmGK6Ccti4F1zpfN2yzbw14btqwwyDQWf3nU="
|
||||
|
||||
assert := internal.NewAssert(t, "TestHmacSha256WithBase64")
|
||||
assert.Equal(expected, hms)
|
||||
}
|
||||
|
||||
func TestHmacSha512(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -87,6 +125,18 @@ func TestHmacSha512(t *testing.T) {
|
||||
assert.Equal(expected, hmacSha512)
|
||||
}
|
||||
|
||||
func TestHmacSha512WithBase64(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
str := "hello"
|
||||
key := "12345"
|
||||
hms := HmacSha512WithBase64(str, key)
|
||||
expected := "3Y8SkKndI9NU4lJtmi6c6M///dN8syCADRxsE9Lvw2Mog3ahlsVFja9T+OGqa0Wm2FYwPVwKIGS/+XhYYdSM/A=="
|
||||
|
||||
assert := internal.NewAssert(t, "TestHmacSha512WithBase64")
|
||||
assert.Equal(expected, hms)
|
||||
}
|
||||
|
||||
func TestSha1(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -98,6 +148,16 @@ func TestSha1(t *testing.T) {
|
||||
assert.Equal(expected, sha1)
|
||||
}
|
||||
|
||||
func TestSha1WithBase64(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
str := Sha1WithBase64("hello")
|
||||
expected := "qvTGHdzF6KLavt4PO0gs2a6pQ00="
|
||||
|
||||
assert := internal.NewAssert(t, "TestSha1WithBase64")
|
||||
assert.Equal(expected, str)
|
||||
}
|
||||
|
||||
func TestSha256(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -109,6 +169,16 @@ func TestSha256(t *testing.T) {
|
||||
assert.Equal(expected, sha256)
|
||||
}
|
||||
|
||||
func TestSha256WithBase64(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
str := Sha256WithBase64("hello")
|
||||
expected := "LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ="
|
||||
|
||||
assert := internal.NewAssert(t, "TestSha256WithBase64")
|
||||
assert.Equal(expected, str)
|
||||
}
|
||||
|
||||
func TestSha512(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -119,3 +189,13 @@ func TestSha512(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSha512")
|
||||
assert.Equal(expected, sha512)
|
||||
}
|
||||
|
||||
func TestSha512WithBase64(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
str := Sha512WithBase64("hello")
|
||||
expected := "m3HSJL1i83hdltRq0+o9czGb+8KJDKra4t/3JRlnPKcjI8PZm6XBHXx6zG4UuMXaDEZjR1wuXDre9G9zvN7AQw=="
|
||||
|
||||
assert := internal.NewAssert(t, "TestSha512WithBase64")
|
||||
assert.Equal(expected, str)
|
||||
}
|
||||
|
||||
@@ -322,7 +322,6 @@ func ExampleHmacMd5() {
|
||||
key := "12345"
|
||||
|
||||
hms := HmacMd5(str, key)
|
||||
|
||||
fmt.Println(hms)
|
||||
|
||||
// Output:
|
||||
@@ -334,37 +333,67 @@ func ExampleHmacSha1() {
|
||||
key := "12345"
|
||||
|
||||
hms := HmacSha1(str, key)
|
||||
|
||||
fmt.Println(hms)
|
||||
|
||||
// Output:
|
||||
// 5c6a9db0cccb92e36ed0323fd09b7f936de9ace0
|
||||
}
|
||||
|
||||
func ExampleHmacSha1WithBase64() {
|
||||
str := "hello"
|
||||
key := "12345"
|
||||
|
||||
hms := HmacSha1WithBase64(str, key)
|
||||
fmt.Println(hms)
|
||||
|
||||
// Output:
|
||||
// XGqdsMzLkuNu0DI/0Jt/k23prOA=
|
||||
}
|
||||
|
||||
func ExampleHmacSha256() {
|
||||
str := "hello"
|
||||
key := "12345"
|
||||
|
||||
hms := HmacSha256(str, key)
|
||||
|
||||
fmt.Println(hms)
|
||||
|
||||
// Output:
|
||||
// 315bb93c4e989862ba09cb62e05d73a5f376cb36f0d786edab0c320d059fde75
|
||||
}
|
||||
|
||||
func ExampleHmacSha256WithBase64() {
|
||||
str := "hello"
|
||||
key := "12345"
|
||||
|
||||
hms := HmacSha256WithBase64(str, key)
|
||||
fmt.Println(hms)
|
||||
|
||||
// Output:
|
||||
// MVu5PE6YmGK6Ccti4F1zpfN2yzbw14btqwwyDQWf3nU=
|
||||
}
|
||||
|
||||
func ExampleHmacSha512() {
|
||||
str := "hello"
|
||||
key := "12345"
|
||||
|
||||
hms := HmacSha512(str, key)
|
||||
|
||||
fmt.Println(hms)
|
||||
|
||||
// Output:
|
||||
// dd8f1290a9dd23d354e2526d9a2e9ce8cffffdd37cb320800d1c6c13d2efc363288376a196c5458daf53f8e1aa6b45a6d856303d5c0a2064bff9785861d48cfc
|
||||
}
|
||||
|
||||
func ExampleHmacSha512WithBase64() {
|
||||
str := "hello"
|
||||
key := "12345"
|
||||
|
||||
hms := HmacSha512WithBase64(str, key)
|
||||
fmt.Println(hms)
|
||||
|
||||
// Output:
|
||||
// 3Y8SkKndI9NU4lJtmi6c6M///dN8syCADRxsE9Lvw2Mog3ahlsVFja9T+OGqa0Wm2FYwPVwKIGS/+XhYYdSM/A==
|
||||
}
|
||||
|
||||
func ExampleMd5String() {
|
||||
md5Str := Md5String("hello")
|
||||
fmt.Println(md5Str)
|
||||
@@ -373,6 +402,14 @@ func ExampleMd5String() {
|
||||
// 5d41402abc4b2a76b9719d911017c592
|
||||
}
|
||||
|
||||
func ExampleMd5StringWithBase64() {
|
||||
md5Str := Md5StringWithBase64("hello")
|
||||
fmt.Println(md5Str)
|
||||
|
||||
// Output:
|
||||
// XUFAKrxLKna5cZ2REBfFkg==
|
||||
}
|
||||
|
||||
func ExampleMd5Byte() {
|
||||
md5Str := Md5Byte([]byte{'a'})
|
||||
fmt.Println(md5Str)
|
||||
@@ -380,6 +417,15 @@ func ExampleMd5Byte() {
|
||||
// Output:
|
||||
// 0cc175b9c0f1b6a831c399e269772661
|
||||
}
|
||||
|
||||
func ExampleMd5ByteWithBase64() {
|
||||
md5Str := Md5ByteWithBase64([]byte("hello"))
|
||||
fmt.Println(md5Str)
|
||||
|
||||
// Output:
|
||||
// XUFAKrxLKna5cZ2REBfFkg==
|
||||
}
|
||||
|
||||
func ExampleSha1() {
|
||||
result := Sha1("hello")
|
||||
fmt.Println(result)
|
||||
@@ -388,6 +434,14 @@ func ExampleSha1() {
|
||||
// aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
|
||||
}
|
||||
|
||||
func ExampleSha1WithBase64() {
|
||||
result := Sha1WithBase64("hello")
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// qvTGHdzF6KLavt4PO0gs2a6pQ00=
|
||||
}
|
||||
|
||||
func ExampleSha256() {
|
||||
result := Sha256("hello")
|
||||
fmt.Println(result)
|
||||
@@ -396,6 +450,14 @@ func ExampleSha256() {
|
||||
// 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
|
||||
}
|
||||
|
||||
func ExampleSha256WithBase64() {
|
||||
result := Sha256WithBase64("hello")
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=
|
||||
}
|
||||
|
||||
func ExampleSha512() {
|
||||
result := Sha512("hello")
|
||||
fmt.Println(result)
|
||||
@@ -403,3 +465,11 @@ func ExampleSha512() {
|
||||
// Output:
|
||||
// 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043
|
||||
}
|
||||
|
||||
func ExampleSha512WithBase64() {
|
||||
result := Sha512WithBase64("hello")
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// m3HSJL1i83hdltRq0+o9czGb+8KJDKra4t/3JRlnPKcjI8PZm6XBHXx6zG4UuMXaDEZjR1wuXDre9G9zvN7AQw==
|
||||
}
|
||||
|
||||
@@ -97,13 +97,13 @@ func GetNowDateTime() string {
|
||||
}
|
||||
|
||||
// GetTodayStartTime return the start time of today, format: yyyy-mm-dd 00:00:00.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/84siyYF7t99
|
||||
func GetTodayStartTime() string {
|
||||
return time.Now().Format("2006-01-02") + " 00:00:00"
|
||||
}
|
||||
|
||||
// GetTodayEndTime return the end time of today, format: yyyy-mm-dd 23:59:59.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/jjrLnfoqgn3
|
||||
func GetTodayEndTime() string {
|
||||
return time.Now().Format("2006-01-02") + " 23:59:59"
|
||||
}
|
||||
|
||||
@@ -717,7 +717,7 @@ func main() {
|
||||
|
||||
### <span id="GetTodayStartTime">GetTodayStartTime</span>
|
||||
|
||||
<p>返回当天开始时间, 格式: yyyy-mm-dd 00:00:00.</p>
|
||||
<p>返回当天开始时间, 格式: yyyy-mm-dd 00:00:00。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
@@ -746,7 +746,7 @@ func main() {
|
||||
|
||||
### <span id="GetTodayEndTime">GetTodayEndTime</span>
|
||||
|
||||
<p>返回当天结束时间,格式: yyyy-mm-dd 23:59:59.</p>
|
||||
<p>返回当天结束时间,格式: yyyy-mm-dd 23:59:59。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ func main() {
|
||||
|
||||
### <span id="CreateDir">CreateDir</span>
|
||||
|
||||
<p>Create directory in absolute path. param `absPath` like /a/, /a/b/.</p>
|
||||
<p>Create directory in absolute path. param `absPath` like /a, /a/b.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
@@ -127,7 +127,7 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := fileutil.CreateDir("/a/")
|
||||
err := fileutil.CreateDir("/a/b") // will create folder /a/b
|
||||
fmt.Println(err)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -108,7 +108,7 @@ func main() {
|
||||
|
||||
### <span id="CreateDir">CreateDir</span>
|
||||
|
||||
<p>使用绝对路径创建嵌套目录,例如/a/, /a/b/</p>
|
||||
<p>使用绝对路径创建嵌套目录,例如/a/, /a/b</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
@@ -127,7 +127,7 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := fileutil.CreateDir("/a/")
|
||||
err := fileutil.CreateDir("/a/b") // will create folder /a/b
|
||||
fmt.Println(err)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -43,6 +43,7 @@ import (
|
||||
- [Merge](#Merge)
|
||||
- [Minus](#Minus)
|
||||
- [IsDisjoint](#IsDisjoint)
|
||||
- [HasKey](#HasKey)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -893,7 +894,7 @@ func main() {
|
||||
|
||||
### <span id="IsDisjoint">IsDisjoint</span>
|
||||
|
||||
<p>Checks two maps are disjoint if they have no keys in common</p>
|
||||
<p>Checks two maps are disjoint if they have no keys in common.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
@@ -937,3 +938,49 @@ func main() {
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="HasKey">HasKey</span>
|
||||
|
||||
<p>Checks if map has key or not. This function is used to replace the following boilerplate code:</p>
|
||||
|
||||
```go
|
||||
_, haskey := amap["baz"];
|
||||
|
||||
if haskey {
|
||||
fmt.Println("map has key baz")
|
||||
}
|
||||
```
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func HasKey[K comparable, V any](m map[K]V, key K) bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/maputil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
m := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
}
|
||||
|
||||
result1 := HasKey(m, "a")
|
||||
result2 := HasKey(m, "c")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
@@ -43,6 +43,7 @@ import (
|
||||
- [Merge](#Merge)
|
||||
- [Minus](#Minus)
|
||||
- [IsDisjoint](#IsDisjoint)
|
||||
- [HasKey](#HasKey)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -932,3 +933,49 @@ func main() {
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="HasKey">HasKey</span>
|
||||
|
||||
<p>检查map是否包含某个key。用于代替以下样板代码:</p>
|
||||
|
||||
```go
|
||||
_, haskey := amap["baz"];
|
||||
|
||||
if haskey {
|
||||
fmt.Println("map has key baz")
|
||||
}
|
||||
```
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func HasKey[K comparable, V any](m map[K]V, key K) bool
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/maputil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
m := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
}
|
||||
|
||||
result1 := HasKey(m, "a")
|
||||
result2 := HasKey(m, "c")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
@@ -24,6 +24,8 @@ import (
|
||||
|
||||
- [Of](#Of)
|
||||
- [Unwrap](#Unwrap)
|
||||
- [UnwarpOr](#UnwarpOr)
|
||||
- [UnwarpOrDefault](#UnwarpOrDefault)
|
||||
- [ExtractPointer](#ExtractPointer)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
@@ -100,6 +102,97 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="UnwarpOr">UnwarpOr</span>
|
||||
|
||||
<p>Returns the value from the pointer or fallback if the pointer is nil.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
```go
|
||||
UnwarpOr[T any](p *T, fallback T) T
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/pointer"
|
||||
)
|
||||
|
||||
func main() {
|
||||
a := 123
|
||||
b := "abc"
|
||||
|
||||
var c *int
|
||||
var d *string
|
||||
|
||||
result1 := pointer.UnwarpOr(&a, 456)
|
||||
result2 := pointer.UnwarpOr(&b, "abc")
|
||||
result3 := pointer.UnwarpOr(c, 456)
|
||||
result4 := pointer.UnwarpOr(d, "def")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
|
||||
// Output:
|
||||
// 123
|
||||
// abc
|
||||
// 456
|
||||
// def
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="UnwarpOrDefault">UnwarpOrDefault</span>
|
||||
|
||||
<p>Returns the value from the pointer or the default value if the pointer is nil.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
```go
|
||||
UnwarpOrDefault[T any](p *T) T
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/pointer"
|
||||
)
|
||||
|
||||
func main() {
|
||||
a := 123
|
||||
b := "abc"
|
||||
|
||||
var c *int
|
||||
var d *string
|
||||
|
||||
result1 := pointer.UnwarpOrDefault(&a)
|
||||
result2 := pointer.UnwarpOrDefault(&b)
|
||||
result3 := pointer.UnwarpOrDefault(c)
|
||||
result4 := pointer.UnwarpOrDefault(d)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
|
||||
// Output:
|
||||
// 123
|
||||
// abc
|
||||
// 0
|
||||
//
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="ExtractPointer">ExtractPointer</span>
|
||||
|
||||
<p>Returns the underlying value by the given interface type</p>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Pointer
|
||||
|
||||
pointer包支持一些指针类型的操作。
|
||||
pointer 包支持一些指针类型的操作。
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -25,6 +25,8 @@ import (
|
||||
- [Of](#Of)
|
||||
- [Unwrap](#Unwrap)
|
||||
- [ExtractPointer](#ExtractPointer)
|
||||
- [UnwarpOr](#UnwarpOr)
|
||||
- [UnwarpOrDefault](#UnwarpOrDefault)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -63,7 +65,6 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="Unwrap">Unwrap</span>
|
||||
|
||||
<p>返回传入指针指向的值。</p>
|
||||
@@ -133,4 +134,94 @@ func main() {
|
||||
// Output:
|
||||
// 1
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
### <span id="UnwarpOr">UnwarpOr</span>
|
||||
|
||||
<p>返回指针的值,如果指针为零值,则返回fallback。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
UnwarpOr[T any](p *T, fallback T) T
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/pointer"
|
||||
)
|
||||
|
||||
func main() {
|
||||
a := 123
|
||||
b := "abc"
|
||||
|
||||
var c *int
|
||||
var d *string
|
||||
|
||||
result1 := pointer.UnwarpOr(&a, 456)
|
||||
result2 := pointer.UnwarpOr(&b, "abc")
|
||||
result3 := pointer.UnwarpOr(c, 456)
|
||||
result4 := pointer.UnwarpOr(d, "def")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
|
||||
// Output:
|
||||
// 123
|
||||
// abc
|
||||
// 456
|
||||
// def
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="UnwarpOrDefault">UnwarpOrDefault</span>
|
||||
|
||||
<p>返回指针的值,如果指针为零值,则返回相应零值。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
UnwarpOrDefault[T any](p *T) T
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/pointer"
|
||||
)
|
||||
|
||||
func main() {
|
||||
a := 123
|
||||
b := "abc"
|
||||
|
||||
var c *int
|
||||
var d *string
|
||||
|
||||
result1 := pointer.UnwarpOrDefault(&a)
|
||||
result2 := pointer.UnwarpOrDefault(&b)
|
||||
result3 := pointer.UnwarpOrDefault(c)
|
||||
result4 := pointer.UnwarpOrDefault(d)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
|
||||
// Output:
|
||||
// 123
|
||||
// abc
|
||||
// 0
|
||||
//
|
||||
}
|
||||
```
|
||||
|
||||
@@ -90,6 +90,7 @@ import (
|
||||
- [UpdateAt](#UpdateAt)
|
||||
- [Without](#Without)
|
||||
- [KeyBy](#KeyBy)
|
||||
- [Join](#Join)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -2417,3 +2418,36 @@ func main() {
|
||||
// map[1:a 2:ab 3:abc]
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="Join">Join</span>
|
||||
|
||||
<p>Join the slice item with specify separator.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Join[T any](s []T, separator string) string
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/slice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
nums := []int{1, 2, 3, 4, 5}
|
||||
|
||||
result1 := slice.Join(nums, ",")
|
||||
result2 := slice.Join(nums, "-")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// 1,2,3,4,5
|
||||
// 1-2-3-4-5
|
||||
}
|
||||
```
|
||||
|
||||
@@ -90,6 +90,7 @@ import (
|
||||
- [UpdateAt](#UpdateAt)
|
||||
- [Without](#Without)
|
||||
- [KeyBy](#KeyBy)
|
||||
- [Join](#Join)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -2390,7 +2391,7 @@ func main() {
|
||||
|
||||
### <span id="KeyBy">KeyBy</span>
|
||||
|
||||
<p>将切片每个元素调用函数后转为map</p>
|
||||
<p>将切片每个元素调用函数后转为map。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
@@ -2417,3 +2418,36 @@ func main() {
|
||||
// map[1:a 2:ab 3:abc]
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="Join">Join</span>
|
||||
|
||||
<p>用指定的分隔符链接切片元素。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Join[T any](s []T, separator string) string
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/slice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
nums := []int{1, 2, 3, 4, 5}
|
||||
|
||||
result1 := slice.Join(nums, ",")
|
||||
result2 := slice.Join(nums, "-")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// 1,2,3,4,5
|
||||
// 1-2-3-4-5
|
||||
}
|
||||
```
|
||||
|
||||
@@ -237,9 +237,9 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
t := tuple.NewTuple2(1, 0.1, "a")
|
||||
t := tuple.NewTuple3(1, 0.1, "a")
|
||||
v1, v2, v3 := t.Unbox()
|
||||
fmt.Printf("%v %v %v", t.FieldA, t.FieldB, t.FieldC)
|
||||
fmt.Printf("%v %v %v", v1, v2, v3)
|
||||
|
||||
// Output: 1 0.1 a
|
||||
}
|
||||
@@ -1134,8 +1134,6 @@ func main() {
|
||||
fmt.Printf("%v %v %v %v %v %v %v %v %v %v", v1, v2, v3, v4, v5, v6, v7, v8, v9, v10)
|
||||
|
||||
// Output: 1 0.1 a true 2 2.2 b c map[a:1] {a}
|
||||
|
||||
// Output: 1 0.1 a true 2 2.2 b c map[a:1]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -239,7 +239,7 @@ import (
|
||||
func main() {
|
||||
t := tuple.NewTuple2(1, 0.1, "a")
|
||||
v1, v2, v3 := t.Unbox()
|
||||
fmt.Printf("%v %v %v", t.FieldA, t.FieldB, t.FieldC)
|
||||
fmt.Printf("%v %v %v", v1, v2, v3)
|
||||
|
||||
// Output: 1 0.1 a
|
||||
}
|
||||
@@ -1134,8 +1134,6 @@ func main() {
|
||||
fmt.Printf("%v %v %v %v %v %v %v %v %v %v", v1, v2, v3, v4, v5, v6, v7, v8, v9, v10)
|
||||
|
||||
// Output: 1 0.1 a true 2 2.2 b c map[a:1] {a}
|
||||
|
||||
// Output: 1 0.1 a true 2 2.2 b c map[a:1]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -52,7 +52,8 @@ func CreateFile(path string) bool {
|
||||
// CreateDir create directory in absolute path. param `absPath` like /a/, /a/b/.
|
||||
// Play: https://go.dev/play/p/qUuCe1OGQnM
|
||||
func CreateDir(absPath string) error {
|
||||
return os.MkdirAll(path.Dir(absPath), os.ModePerm)
|
||||
// return os.MkdirAll(path.Dir(absPath), os.ModePerm)
|
||||
return os.MkdirAll(absPath, os.ModePerm)
|
||||
}
|
||||
|
||||
// IsDir checks if the path is directory or not.
|
||||
|
||||
@@ -39,7 +39,7 @@ func ExampleCreateFile() {
|
||||
|
||||
func ExampleCreateDir() {
|
||||
pwd, _ := os.Getwd()
|
||||
dirPath := pwd + "/test_xxx/"
|
||||
dirPath := pwd + "/createdir/a/b"
|
||||
|
||||
result1 := IsExist(dirPath)
|
||||
|
||||
@@ -48,16 +48,22 @@ func ExampleCreateDir() {
|
||||
return
|
||||
}
|
||||
|
||||
result2 := IsExist(dirPath)
|
||||
|
||||
os.Remove(dirPath)
|
||||
result2 := IsExist(pwd + "/createdir/")
|
||||
result3 := IsExist(pwd + "/createdir/a")
|
||||
result4 := IsExist(pwd + "/createdir/a/b")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
|
||||
os.RemoveAll(pwd + "/createdir/")
|
||||
|
||||
// Output:
|
||||
// false
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
}
|
||||
|
||||
func ExampleIsDir() {
|
||||
|
||||
@@ -50,7 +50,7 @@ func TestCreateDir(t *testing.T) {
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
dirPath := pwd + "/a/"
|
||||
dirPath := pwd + "/a/b"
|
||||
err = CreateDir(dirPath)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
@@ -58,7 +58,9 @@ func TestCreateDir(t *testing.T) {
|
||||
}
|
||||
|
||||
assert.Equal(true, IsExist(dirPath))
|
||||
os.Remove(dirPath)
|
||||
|
||||
os.RemoveAll(pwd + "/a")
|
||||
|
||||
assert.Equal(false, IsExist(dirPath))
|
||||
}
|
||||
|
||||
|
||||
154
maputil/concurrentmap.go
Normal file
154
maputil/concurrentmap.go
Normal file
@@ -0,0 +1,154 @@
|
||||
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
|
||||
// Use of this source code is governed by MIT license
|
||||
|
||||
// Package maputil includes some functions to manipulate map.
|
||||
package maputil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const defaultShardCount = 32
|
||||
|
||||
// ConcurrentMap is like map, but is safe for concurrent use by multiple goroutines.
|
||||
type ConcurrentMap[K comparable, V any] struct {
|
||||
shardCount uint64
|
||||
locks []sync.RWMutex
|
||||
maps []map[K]V
|
||||
}
|
||||
|
||||
// NewConcurrentMap create a ConcurrentMap with specific shard count.
|
||||
func NewConcurrentMap[K comparable, V any](shardCount int) *ConcurrentMap[K, V] {
|
||||
if shardCount <= 0 {
|
||||
shardCount = defaultShardCount
|
||||
}
|
||||
|
||||
cm := &ConcurrentMap[K, V]{
|
||||
shardCount: uint64(shardCount),
|
||||
locks: make([]sync.RWMutex, shardCount),
|
||||
maps: make([]map[K]V, shardCount),
|
||||
}
|
||||
|
||||
for i := range cm.maps {
|
||||
cm.maps[i] = make(map[K]V)
|
||||
}
|
||||
|
||||
return cm
|
||||
}
|
||||
|
||||
// Set the value for a key.
|
||||
// Play: todo
|
||||
func (cm *ConcurrentMap[K, V]) Set(key K, value V) {
|
||||
shard := cm.getShard(key)
|
||||
|
||||
cm.locks[shard].Lock()
|
||||
cm.maps[shard][key] = value
|
||||
|
||||
cm.locks[shard].Unlock()
|
||||
}
|
||||
|
||||
// Get the value stored in the map for a key, or nil if no.
|
||||
// Play: todo
|
||||
func (cm *ConcurrentMap[K, V]) Get(key K) (V, bool) {
|
||||
shard := cm.getShard(key)
|
||||
|
||||
cm.locks[shard].RLock()
|
||||
value, ok := cm.maps[shard][key]
|
||||
cm.locks[shard].RUnlock()
|
||||
|
||||
return value, ok
|
||||
}
|
||||
|
||||
// GetOrSet returns the existing value for the key if present.
|
||||
// Otherwise, it sets and returns the given value.
|
||||
// Play: todo
|
||||
func (cm *ConcurrentMap[K, V]) GetOrSet(key K, value V) (actual V, ok bool) {
|
||||
shard := cm.getShard(key)
|
||||
|
||||
cm.locks[shard].RLock()
|
||||
if actual, ok := cm.maps[shard][key]; ok {
|
||||
cm.locks[shard].RUnlock()
|
||||
return actual, ok
|
||||
}
|
||||
cm.locks[shard].RUnlock()
|
||||
|
||||
// lock again
|
||||
cm.locks[shard].Lock()
|
||||
if actual, ok = cm.maps[shard][key]; ok {
|
||||
cm.locks[shard].Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
cm.maps[shard][key] = value
|
||||
cm.locks[shard].Unlock()
|
||||
|
||||
return value, ok
|
||||
}
|
||||
|
||||
// Delete the value for a key.
|
||||
// Play: todo
|
||||
func (cm *ConcurrentMap[K, V]) Delete(key K) {
|
||||
shard := cm.getShard(key)
|
||||
|
||||
cm.locks[shard].Lock()
|
||||
delete(cm.maps[shard], key)
|
||||
cm.locks[shard].Unlock()
|
||||
}
|
||||
|
||||
// GetAndDelete returns the existing value for the key if present and then delete the value for the key.
|
||||
// Otherwise, do nothing, just return false
|
||||
// Play: todo
|
||||
func (cm *ConcurrentMap[K, V]) GetAndDelete(key K) (actual V, ok bool) {
|
||||
shard := cm.getShard(key)
|
||||
|
||||
cm.locks[shard].RLock()
|
||||
if actual, ok = cm.maps[shard][key]; ok {
|
||||
cm.locks[shard].RUnlock()
|
||||
cm.Delete(key)
|
||||
return
|
||||
}
|
||||
cm.locks[shard].RUnlock()
|
||||
|
||||
return actual, false
|
||||
}
|
||||
|
||||
// Has checks if map has the value for a key.
|
||||
// Play: todo
|
||||
func (cm *ConcurrentMap[K, V]) Has(key K) bool {
|
||||
_, ok := cm.Get(key)
|
||||
return ok
|
||||
}
|
||||
|
||||
// Range calls iterator sequentially for each key and value present in each of the shards in the map.
|
||||
// If iterator returns false, range stops the iteration.
|
||||
func (cm *ConcurrentMap[K, V]) Range(iterator func(key K, value V) bool) {
|
||||
for shard := range cm.locks {
|
||||
cm.locks[shard].RLock()
|
||||
|
||||
for k, v := range cm.maps[shard] {
|
||||
if !iterator(k, v) {
|
||||
cm.locks[shard].RUnlock()
|
||||
return
|
||||
}
|
||||
}
|
||||
cm.locks[shard].RUnlock()
|
||||
}
|
||||
}
|
||||
|
||||
// getShard get shard by a key.
|
||||
func (cm *ConcurrentMap[K, V]) getShard(key K) uint64 {
|
||||
hash := fnv32(fmt.Sprintf("%v", key))
|
||||
return uint64(hash) % cm.shardCount
|
||||
}
|
||||
|
||||
func fnv32(key string) uint32 {
|
||||
hash := uint32(2166136261)
|
||||
const prime32 = uint32(16777619)
|
||||
keyLength := len(key)
|
||||
for i := 0; i < keyLength; i++ {
|
||||
hash *= prime32
|
||||
hash ^= uint32(key[i])
|
||||
}
|
||||
return hash
|
||||
}
|
||||
123
maputil/concurrentmap_test.go
Normal file
123
maputil/concurrentmap_test.go
Normal file
@@ -0,0 +1,123 @@
|
||||
package maputil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestConcurrentMap_Set_Get(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestConcurrentMap_Set_Get")
|
||||
|
||||
cm := NewConcurrentMap[string, int](100)
|
||||
|
||||
var wg1 sync.WaitGroup
|
||||
wg1.Add(10)
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
go func(n int) {
|
||||
cm.Set(fmt.Sprintf("%d", n), n)
|
||||
wg1.Done()
|
||||
}(i)
|
||||
}
|
||||
wg1.Wait()
|
||||
|
||||
var wg2 sync.WaitGroup
|
||||
wg2.Add(10)
|
||||
for j := 0; j < 10; j++ {
|
||||
go func(n int) {
|
||||
val, ok := cm.Get(fmt.Sprintf("%d", n))
|
||||
assert.Equal(n, val)
|
||||
assert.Equal(true, ok)
|
||||
wg2.Done()
|
||||
}(j)
|
||||
}
|
||||
wg2.Wait()
|
||||
}
|
||||
|
||||
func TestConcurrentMap_GetOrSet(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestConcurrentMap_GetOrSet")
|
||||
|
||||
cm := NewConcurrentMap[string, int](100)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(5)
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
go func(n int) {
|
||||
val, ok := cm.GetOrSet(fmt.Sprintf("%d", n), n)
|
||||
assert.Equal(n, val)
|
||||
assert.Equal(false, ok)
|
||||
wg.Done()
|
||||
}(i)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
for j := 0; j < 5; j++ {
|
||||
go func(n int) {
|
||||
val, ok := cm.Get(fmt.Sprintf("%d", n))
|
||||
assert.Equal(n, val)
|
||||
assert.Equal(true, ok)
|
||||
}(j)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConcurrentMap_Delete(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestConcurrentMap_Delete")
|
||||
|
||||
cm := NewConcurrentMap[string, int](100)
|
||||
|
||||
var wg1 sync.WaitGroup
|
||||
wg1.Add(10)
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
go func(n int) {
|
||||
cm.Set(fmt.Sprintf("%d", n), n)
|
||||
wg1.Done()
|
||||
}(i)
|
||||
}
|
||||
wg1.Wait()
|
||||
|
||||
var wg2 sync.WaitGroup
|
||||
wg2.Add(10)
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
go func(n int) {
|
||||
cm.Delete(fmt.Sprintf("%d", n))
|
||||
wg2.Done()
|
||||
}(i)
|
||||
}
|
||||
wg2.Wait()
|
||||
|
||||
for j := 0; j < 10; j++ {
|
||||
go func(n int) {
|
||||
_, ok := cm.Get(fmt.Sprintf("%d", n))
|
||||
assert.Equal(false, ok)
|
||||
}(j)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConcurrentMap_GetAndDelete(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestConcurrentMap_GetAndDelete")
|
||||
|
||||
cm := NewConcurrentMap[string, int](100)
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
go func(n int) {
|
||||
cm.Set(fmt.Sprintf("%d", n), n)
|
||||
}(i)
|
||||
}
|
||||
|
||||
for j := 0; j < 10; j++ {
|
||||
go func(n int) {
|
||||
val, ok := cm.GetAndDelete(fmt.Sprintf("%d", n))
|
||||
assert.Equal(n, val)
|
||||
assert.Equal(true, ok)
|
||||
|
||||
_, ok = cm.Get(fmt.Sprintf("%d", n))
|
||||
assert.Equal(false, ok)
|
||||
}(j)
|
||||
}
|
||||
}
|
||||
@@ -289,3 +289,17 @@ func MapValues[K comparable, V any, T any](m map[K]V, iteratee func(key K, value
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// HasKey checks if map has key or not.
|
||||
// This function is used to replace the following boilerplate code:
|
||||
// _, haskey := amap["baz"];
|
||||
//
|
||||
// if haskey {
|
||||
// fmt.Println("map has key baz")
|
||||
// }
|
||||
//
|
||||
// Play: todo
|
||||
func HasKey[K comparable, V any](m map[K]V, key K) bool {
|
||||
_, haskey := m[key]
|
||||
return haskey
|
||||
}
|
||||
|
||||
@@ -433,3 +433,20 @@ func ExampleMapTo() {
|
||||
// <nil>
|
||||
// {Nothin 28 123456789 {test 1}}
|
||||
}
|
||||
|
||||
func ExampleHasKey() {
|
||||
m := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
}
|
||||
|
||||
result1 := HasKey(m, "a")
|
||||
result2 := HasKey(m, "c")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// false
|
||||
}
|
||||
|
||||
@@ -458,3 +458,17 @@ func TestMapValues(t *testing.T) {
|
||||
|
||||
assert.Equal(expected, result)
|
||||
}
|
||||
|
||||
func TestHasKey(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := internal.NewAssert(t, "TestHasKey")
|
||||
|
||||
m := map[string]int{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
}
|
||||
|
||||
assert.Equal(true, HasKey(m, "a"))
|
||||
assert.Equal(false, HasKey(m, "c"))
|
||||
}
|
||||
|
||||
@@ -18,6 +18,26 @@ func Unwrap[T any](p *T) T {
|
||||
return *p
|
||||
}
|
||||
|
||||
// UnwarpOr returns the value from the pointer or fallback if the pointer is nil.
|
||||
// Play: https://go.dev/play/p/mmNaLC38W8C
|
||||
func UnwarpOr[T any](p *T, fallback T) T {
|
||||
if p == nil {
|
||||
return fallback
|
||||
}
|
||||
return *p
|
||||
}
|
||||
|
||||
// UnwarpOrDefault returns the value from the pointer or the default value if the pointer is nil.
|
||||
// Play: https://go.dev/play/p/ZnGIHf8_o4E
|
||||
func UnwarpOrDefault[T any](p *T) T {
|
||||
var v T
|
||||
|
||||
if p == nil {
|
||||
return v
|
||||
}
|
||||
return *p
|
||||
}
|
||||
|
||||
// ExtractPointer returns the underlying value by the given interface type
|
||||
// Play: https://go.dev/play/p/D7HFjeWU2ZP
|
||||
func ExtractPointer(value any) any {
|
||||
|
||||
@@ -29,6 +29,54 @@ func ExampleUnwrap() {
|
||||
// abc
|
||||
}
|
||||
|
||||
func ExampleUnwarpOr() {
|
||||
a := 123
|
||||
b := "abc"
|
||||
|
||||
var c *int
|
||||
var d *string
|
||||
|
||||
result1 := UnwarpOr(&a, 456)
|
||||
result2 := UnwarpOr(&b, "abc")
|
||||
result3 := UnwarpOr(c, 456)
|
||||
result4 := UnwarpOr(d, "def")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
|
||||
// Output:
|
||||
// 123
|
||||
// abc
|
||||
// 456
|
||||
// def
|
||||
}
|
||||
|
||||
func ExampleUnwarpOrDefault() {
|
||||
a := 123
|
||||
b := "abc"
|
||||
|
||||
var c *int
|
||||
var d *string
|
||||
|
||||
result1 := UnwarpOrDefault(&a)
|
||||
result2 := UnwarpOrDefault(&b)
|
||||
result3 := UnwarpOrDefault(c)
|
||||
result4 := UnwarpOrDefault(d)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
|
||||
// Output:
|
||||
// 123
|
||||
// abc
|
||||
// 0
|
||||
//
|
||||
}
|
||||
|
||||
func ExampleExtractPointer() {
|
||||
a := 1
|
||||
b := &a
|
||||
|
||||
@@ -30,6 +30,40 @@ func TestUnwrap(t *testing.T) {
|
||||
assert.Equal(b, Unwrap(&b))
|
||||
}
|
||||
|
||||
func TestUnwarpOr(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := internal.NewAssert(t, "TestUnwarpOr")
|
||||
|
||||
a := 123
|
||||
b := "abc"
|
||||
|
||||
var c *int
|
||||
var d *string
|
||||
|
||||
assert.Equal(a, UnwarpOr(&a, 456))
|
||||
assert.Equal(b, UnwarpOr(&b, "abc"))
|
||||
assert.Equal(456, UnwarpOr(c, 456))
|
||||
assert.Equal("def", UnwarpOr(d, "def"))
|
||||
}
|
||||
|
||||
func TestUnwarpOrDefault(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := internal.NewAssert(t, "TestUnwarpOrDefault")
|
||||
|
||||
a := 123
|
||||
b := "abc"
|
||||
|
||||
var c *int
|
||||
var d *string
|
||||
|
||||
assert.Equal(a, UnwarpOrDefault(&a))
|
||||
assert.Equal(b, UnwarpOrDefault(&b))
|
||||
assert.Equal(0, UnwarpOrDefault(c))
|
||||
assert.Equal("", UnwarpOrDefault(d))
|
||||
}
|
||||
|
||||
func TestExtractPointer(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"math/rand"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/exp/constraints"
|
||||
@@ -436,8 +437,8 @@ func flattenRecursive(value reflect.Value, result reflect.Value) reflect.Value {
|
||||
// ForEach iterates over elements of slice and invokes function for each element.
|
||||
// Play: https://go.dev/play/p/DrPaa4YsHRF
|
||||
func ForEach[T any](slice []T, iteratee func(index int, item T)) {
|
||||
for i, v := range slice {
|
||||
iteratee(i, v)
|
||||
for i := 0; i < len(slice); i++ {
|
||||
iteratee(i, slice[i])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,8 +446,8 @@ func ForEach[T any](slice []T, iteratee func(index int, item T)) {
|
||||
// when iteratee return false, will break the for each loop.
|
||||
// Play: https://go.dev/play/p/qScs39f3D9W
|
||||
func ForEachWithBreak[T any](slice []T, iteratee func(index int, item T) bool) {
|
||||
for i, v := range slice {
|
||||
if !iteratee(i, v) {
|
||||
for i := 0; i < len(slice); i++ {
|
||||
if !iteratee(i, slice[i]) {
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -457,8 +458,8 @@ func ForEachWithBreak[T any](slice []T, iteratee func(index int, item T) bool) {
|
||||
func Map[T any, U any](slice []T, iteratee func(index int, item T) U) []U {
|
||||
result := make([]U, len(slice), cap(slice))
|
||||
|
||||
for i, v := range slice {
|
||||
result[i] = iteratee(i, v)
|
||||
for i := 0; i < len(slice); i++ {
|
||||
result[i] = iteratee(i, slice[i])
|
||||
}
|
||||
|
||||
return result
|
||||
@@ -1188,3 +1189,13 @@ func KeyBy[T any, U comparable](slice []T, iteratee func(item T) U) map[U]T {
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Join the slice item with specify separator.
|
||||
// Play: todo
|
||||
func Join[T any](s []T, separator string) string {
|
||||
str := Map(s, func(_ int, item T) string {
|
||||
return fmt.Sprint(item)
|
||||
})
|
||||
|
||||
return strings.Join(str, separator)
|
||||
}
|
||||
|
||||
@@ -1032,3 +1032,17 @@ func ExampleKeyBy() {
|
||||
// Output:
|
||||
// map[1:a 2:ab 3:abc]
|
||||
}
|
||||
|
||||
func ExampleJoin() {
|
||||
nums := []int{1, 2, 3, 4, 5}
|
||||
|
||||
result1 := Join(nums, ",")
|
||||
result2 := Join(nums, "-")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// 1,2,3,4,5
|
||||
// 1-2-3-4-5
|
||||
}
|
||||
|
||||
@@ -1161,3 +1161,17 @@ func TestRepeat(t *testing.T) {
|
||||
assert.Equal([]string{}, Repeat("a", 0))
|
||||
assert.Equal([]string{"a", "a", "a", "a", "a", "a"}, Repeat("a", 6))
|
||||
}
|
||||
|
||||
func TestJoin(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := internal.NewAssert(t, "TestJoin")
|
||||
|
||||
nums := []int{1, 2, 3, 4, 5}
|
||||
|
||||
result1 := Join(nums, ",")
|
||||
result2 := Join(nums, "-")
|
||||
|
||||
assert.Equal("1,2,3,4,5", result1)
|
||||
assert.Equal("1-2-3-4-5", result2)
|
||||
}
|
||||
|
||||
@@ -13,19 +13,19 @@ type Tuple2[A any, B any] struct {
|
||||
}
|
||||
|
||||
// Unbox returns values in tuple.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/0fD1qfCVwjm
|
||||
func (t Tuple2[A, B]) Unbox() (A, B) {
|
||||
return t.FieldA, t.FieldB
|
||||
}
|
||||
|
||||
// NewTuple2 creates a 2 elemnets tuple from a list of values.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/3sHVqBQpLYN
|
||||
func NewTuple2[A any, B any](a A, b B) Tuple2[A, B] {
|
||||
return Tuple2[A, B]{FieldA: a, FieldB: b}
|
||||
}
|
||||
|
||||
// Zip2 create a slice of Tuple2, whose elements are correspond to the given slice elements.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/4ncWJJ77Xio
|
||||
func Zip2[A any, B any](a []A, b []B) []Tuple2[A, B] {
|
||||
size := mathutil.Max(len(a), len(b))
|
||||
|
||||
@@ -42,7 +42,7 @@ func Zip2[A any, B any](a []A, b []B) []Tuple2[A, B] {
|
||||
}
|
||||
|
||||
// Unzip2 creates a group of slice from a slice of Tuple2.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/KBecr60feXb
|
||||
func Unzip2[A any, B any](tuples []Tuple2[A, B]) ([]A, []B) {
|
||||
size := len(tuples)
|
||||
|
||||
@@ -65,19 +65,19 @@ type Tuple3[A any, B any, C any] struct {
|
||||
}
|
||||
|
||||
// Unbox returns values in tuple.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/YojLy-id1BS
|
||||
func (t Tuple3[A, B, C]) Unbox() (A, B, C) {
|
||||
return t.FieldA, t.FieldB, t.FieldC
|
||||
}
|
||||
|
||||
// NewTuple3 creates a 3 elemnets tuple from a list of values.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/FtH2sdCLlCf
|
||||
func NewTuple3[A any, B any, C any](a A, b B, c C) Tuple3[A, B, C] {
|
||||
return Tuple3[A, B, C]{FieldA: a, FieldB: b, FieldC: c}
|
||||
}
|
||||
|
||||
// Zip3 create a slice of Tuple3, whose elements are correspond to the given slice elements.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/97NgmsTILfu
|
||||
func Zip3[A any, B any, C any](a []A, b []B, c []C) []Tuple3[A, B, C] {
|
||||
size := mathutil.Max(len(a), len(b), len(c))
|
||||
|
||||
@@ -95,7 +95,7 @@ func Zip3[A any, B any, C any](a []A, b []B, c []C) []Tuple3[A, B, C] {
|
||||
}
|
||||
|
||||
// Unzip3 creates a group of slice from a slice of Tuple3.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/bba4cpAa7KO
|
||||
func Unzip3[A any, B any, C any](tuples []Tuple3[A, B, C]) ([]A, []B, []C) {
|
||||
size := len(tuples)
|
||||
|
||||
@@ -121,19 +121,19 @@ type Tuple4[A any, B any, C any, D any] struct {
|
||||
}
|
||||
|
||||
// Unbox returns values in tuple.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/ACj9YuACGgW
|
||||
func (t Tuple4[A, B, C, D]) Unbox() (A, B, C, D) {
|
||||
return t.FieldA, t.FieldB, t.FieldC, t.FieldD
|
||||
}
|
||||
|
||||
// NewTuple4 creates a 4 elemnets tuple from a list of values.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/D2EqDz096tk
|
||||
func NewTuple4[A any, B any, C any, D any](a A, b B, c C, d D) Tuple4[A, B, C, D] {
|
||||
return Tuple4[A, B, C, D]{FieldA: a, FieldB: b, FieldC: c, FieldD: d}
|
||||
}
|
||||
|
||||
// Zip4 create a slice of Tuple4, whose elements are correspond to the given slice elements.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/PEmTYVK5hL4
|
||||
func Zip4[A any, B any, C any, D any](a []A, b []B, c []C, d []D) []Tuple4[A, B, C, D] {
|
||||
size := mathutil.Max(len(a), len(b), len(c), len(d))
|
||||
|
||||
@@ -152,7 +152,7 @@ func Zip4[A any, B any, C any, D any](a []A, b []B, c []C, d []D) []Tuple4[A, B,
|
||||
}
|
||||
|
||||
// Unzip4 creates a group of slice from a slice of Tuple4.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/rb8z4gyYSRN
|
||||
func Unzip4[A any, B any, C any, D any](tuples []Tuple4[A, B, C, D]) ([]A, []B, []C, []D) {
|
||||
size := len(tuples)
|
||||
|
||||
@@ -181,19 +181,19 @@ type Tuple5[A any, B any, C any, D any, E any] struct {
|
||||
}
|
||||
|
||||
// Unbox returns values in tuple.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/GyIyZHjCvoS
|
||||
func (t Tuple5[A, B, C, D, E]) Unbox() (A, B, C, D, E) {
|
||||
return t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE
|
||||
}
|
||||
|
||||
// NewTuple5 creates a 5 elemnets tuple from a list of values.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/2WndmVxPg-r
|
||||
func NewTuple5[A any, B any, C any, D any, E any](a A, b B, c C, d D, e E) Tuple5[A, B, C, D, E] {
|
||||
return Tuple5[A, B, C, D, E]{FieldA: a, FieldB: b, FieldC: c, FieldD: d, FieldE: e}
|
||||
}
|
||||
|
||||
// Zip5 create a slice of Tuple5, whose elements are correspond to the given slice elements.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/fCAAJLMfBIP
|
||||
func Zip5[A any, B any, C any, D any, E any](a []A, b []B, c []C, d []D, e []E) []Tuple5[A, B, C, D, E] {
|
||||
size := mathutil.Max(len(a), len(b), len(c), len(d), len(e))
|
||||
|
||||
@@ -215,7 +215,7 @@ func Zip5[A any, B any, C any, D any, E any](a []A, b []B, c []C, d []D, e []E)
|
||||
}
|
||||
|
||||
// Unzip5 creates a group of slice from a slice of Tuple5.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/gyl6vKfhqPb
|
||||
func Unzip5[A any, B any, C any, D any, E any](tuples []Tuple5[A, B, C, D, E]) ([]A, []B, []C, []D, []E) {
|
||||
size := len(tuples)
|
||||
|
||||
@@ -247,19 +247,19 @@ type Tuple6[A any, B any, C any, D any, E any, F any] struct {
|
||||
}
|
||||
|
||||
// Unbox returns values in tuple.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/FjIHV7lpxmW
|
||||
func (t Tuple6[A, B, C, D, E, F]) Unbox() (A, B, C, D, E, F) {
|
||||
return t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF
|
||||
}
|
||||
|
||||
// NewTuple6 creates a 6 elemnets tuple from a list of values.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/VjqcCwEJZbs
|
||||
func NewTuple6[A any, B any, C any, D any, E any, F any](a A, b B, c C, d D, e E, f F) Tuple6[A, B, C, D, E, F] {
|
||||
return Tuple6[A, B, C, D, E, F]{FieldA: a, FieldB: b, FieldC: c, FieldD: d, FieldE: e, FieldF: f}
|
||||
}
|
||||
|
||||
// Zip6 create a slice of Tuple6, whose elements are correspond to the given slice elements.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/oWPrnUYuFHo
|
||||
func Zip6[A any, B any, C any, D any, E any, F any](a []A, b []B, c []C, d []D, e []E, f []F) []Tuple6[A, B, C, D, E, F] {
|
||||
size := mathutil.Max(len(a), len(b), len(c), len(d), len(e), len(f))
|
||||
|
||||
@@ -282,7 +282,7 @@ func Zip6[A any, B any, C any, D any, E any, F any](a []A, b []B, c []C, d []D,
|
||||
}
|
||||
|
||||
// Unzip6 creates a group of slice from a slice of Tuple6.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/l41XFqCyh5E
|
||||
func Unzip6[A any, B any, C any, D any, E any, F any](tuples []Tuple6[A, B, C, D, E, F]) ([]A, []B, []C, []D, []E, []F) {
|
||||
size := len(tuples)
|
||||
|
||||
@@ -317,19 +317,19 @@ type Tuple7[A any, B any, C any, D any, E any, F any, G any] struct {
|
||||
}
|
||||
|
||||
// Unbox returns values in tuple.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/R9I8qeDk0zs
|
||||
func (t Tuple7[A, B, C, D, E, F, G]) Unbox() (A, B, C, D, E, F, G) {
|
||||
return t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG
|
||||
}
|
||||
|
||||
// NewTuple7 creates a 7 elemnets tuple from a list of values.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/dzAgv_Ezub9
|
||||
func NewTuple7[A any, B any, C any, D any, E any, F any, G any](a A, b B, c C, d D, e E, f F, g G) Tuple7[A, B, C, D, E, F, G] {
|
||||
return Tuple7[A, B, C, D, E, F, G]{FieldA: a, FieldB: b, FieldC: c, FieldD: d, FieldE: e, FieldF: f, FieldG: g}
|
||||
}
|
||||
|
||||
// Zip7 create a slice of Tuple7, whose elements are correspond to the given slice elements.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/WUJuo897Egf
|
||||
func Zip7[A any, B any, C any, D any, E any, F any, G any](a []A, b []B, c []C, d []D, e []E, f []F, g []G) []Tuple7[A, B, C, D, E, F, G] {
|
||||
size := mathutil.Max(len(a), len(b), len(c), len(d), len(e), len(f), len(g))
|
||||
|
||||
@@ -354,7 +354,7 @@ func Zip7[A any, B any, C any, D any, E any, F any, G any](a []A, b []B, c []C,
|
||||
}
|
||||
|
||||
// Unzip7 creates a group of slice from a slice of Tuple7.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/hws_P1Fr2j3
|
||||
func Unzip7[A any, B any, C any, D any, E any, F any, G any](tuples []Tuple7[A, B, C, D, E, F, G]) ([]A, []B, []C, []D, []E, []F, []G) {
|
||||
size := len(tuples)
|
||||
|
||||
@@ -392,19 +392,19 @@ type Tuple8[A any, B any, C any, D any, E any, F any, G any, H any] struct {
|
||||
}
|
||||
|
||||
// Unbox returns values in tuple.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/PRxLBBb4SMl
|
||||
func (t Tuple8[A, B, C, D, E, F, G, H]) Unbox() (A, B, C, D, E, F, G, H) {
|
||||
return t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG, t.FieldH
|
||||
}
|
||||
|
||||
// NewTuple8 creates a 8 elemnets tuple from a list of values.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/YA9S0rz3dRz
|
||||
func NewTuple8[A any, B any, C any, D any, E any, F any, G any, H any](a A, b B, c C, d D, e E, f F, g G, h H) Tuple8[A, B, C, D, E, F, G, H] {
|
||||
return Tuple8[A, B, C, D, E, F, G, H]{FieldA: a, FieldB: b, FieldC: c, FieldD: d, FieldE: e, FieldF: f, FieldG: g, FieldH: h}
|
||||
}
|
||||
|
||||
// Zip8 create a slice of Tuple8, whose elements are correspond to the given slice elements.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/8V9jWkuJfaQ
|
||||
func Zip8[A any, B any, C any, D any, E any, F any, G any, H any](a []A, b []B, c []C, d []D, e []E, f []F, g []G, h []H) []Tuple8[A, B, C, D, E, F, G, H] {
|
||||
size := mathutil.Max(len(a), len(b), len(c), len(d), len(e), len(f), len(g), len(h))
|
||||
|
||||
@@ -430,7 +430,7 @@ func Zip8[A any, B any, C any, D any, E any, F any, G any, H any](a []A, b []B,
|
||||
}
|
||||
|
||||
// Unzip8 creates a group of slice from a slice of Tuple8.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/1SndOwGsZB4
|
||||
func Unzip8[A any, B any, C any, D any, E any, F any, G any, H any](tuples []Tuple8[A, B, C, D, E, F, G, H]) ([]A, []B, []C, []D, []E, []F, []G, []H) {
|
||||
size := len(tuples)
|
||||
|
||||
@@ -471,19 +471,19 @@ type Tuple9[A any, B any, C any, D any, E any, F any, G any, H any, I any] struc
|
||||
}
|
||||
|
||||
// Unbox returns values in tuple.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/oFJFGTAuOa8
|
||||
func (t Tuple9[A, B, C, D, E, F, G, H, I]) Unbox() (A, B, C, D, E, F, G, H, I) {
|
||||
return t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG, t.FieldH, t.FieldI
|
||||
}
|
||||
|
||||
// NewTuple9 creates a 9 elemnets tuple from a list of values.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/yS2NGGtZpQr
|
||||
func NewTuple9[A any, B any, C any, D any, E any, F any, G any, H any, I any](a A, b B, c C, d D, e E, f F, g G, h H, i I) Tuple9[A, B, C, D, E, F, G, H, I] {
|
||||
return Tuple9[A, B, C, D, E, F, G, H, I]{FieldA: a, FieldB: b, FieldC: c, FieldD: d, FieldE: e, FieldF: f, FieldG: g, FieldH: h, FieldI: i}
|
||||
}
|
||||
|
||||
// Zip9 create a slice of Tuple9, whose elements are correspond to the given slice elements.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/cgsL15QYnfz
|
||||
func Zip9[A any, B any, C any, D any, E any, F any, G any, H any, I any](a []A, b []B, c []C, d []D, e []E, f []F, g []G, h []H, i []I) []Tuple9[A, B, C, D, E, F, G, H, I] {
|
||||
size := mathutil.Max(len(a), len(b), len(c), len(d), len(e), len(f), len(g), len(h), len(i))
|
||||
|
||||
@@ -510,7 +510,7 @@ func Zip9[A any, B any, C any, D any, E any, F any, G any, H any, I any](a []A,
|
||||
}
|
||||
|
||||
// Unzip9 creates a group of slice from a slice of Tuple9.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/91-BU_KURSA
|
||||
func Unzip9[A any, B any, C any, D any, E any, F any, G any, H any, I any](tuples []Tuple9[A, B, C, D, E, F, G, H, I]) ([]A, []B, []C, []D, []E, []F, []G, []H, []I) {
|
||||
size := len(tuples)
|
||||
|
||||
@@ -554,19 +554,19 @@ type Tuple10[A any, B any, C any, D any, E any, F any, G any, H any, I any, J an
|
||||
}
|
||||
|
||||
// Unbox returns values in tuple.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/qfyx3x_X0Cu
|
||||
func (t Tuple10[A, B, C, D, E, F, G, H, I, J]) Unbox() (A, B, C, D, E, F, G, H, I, J) {
|
||||
return t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG, t.FieldH, t.FieldI, t.FieldJ
|
||||
}
|
||||
|
||||
// NewTuple10 creates a 10 elemnets tuple from a list of values.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/799qqZg0hUv
|
||||
func NewTuple10[A any, B any, C any, D any, E any, F any, G any, H any, I any, J any](a A, b B, c C, d D, e E, f F, g G, h H, i I, j J) Tuple10[A, B, C, D, E, F, G, H, I, J] {
|
||||
return Tuple10[A, B, C, D, E, F, G, H, I, J]{FieldA: a, FieldB: b, FieldC: c, FieldD: d, FieldE: e, FieldF: f, FieldG: g, FieldH: h, FieldI: i, FieldJ: j}
|
||||
}
|
||||
|
||||
// Zip10 create a slice of Tuple10, whose elements are correspond to the given slice elements.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/YSR-2cXnrY4
|
||||
func Zip10[A any, B any, C any, D any, E any, F any, G any, H any, I any, J any](a []A, b []B, c []C, d []D, e []E, f []F, g []G, h []H, i []I, j []J) []Tuple10[A, B, C, D, E, F, G, H, I, J] {
|
||||
size := mathutil.Max(len(a), len(b), len(c), len(d), len(e), len(f), len(g), len(h), len(i), len(j))
|
||||
|
||||
@@ -595,7 +595,7 @@ func Zip10[A any, B any, C any, D any, E any, F any, G any, H any, I any, J any]
|
||||
}
|
||||
|
||||
// Unzip10 creates a group of slice from a slice of Tuple10.
|
||||
// Play: todo
|
||||
// Play: https://go.dev/play/p/-taQB6Wfre_z
|
||||
func Unzip10[A any, B any, C any, D any, E any, F any, G any, H any, I any, J any](tuples []Tuple10[A, B, C, D, E, F, G, H, I, J]) ([]A, []B, []C, []D, []E, []F, []G, []H, []I, []J) {
|
||||
size := len(tuples)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user