mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-04 21:02:27 +08:00
Compare commits
178 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fafb59dad6 | ||
|
|
e36c01cac9 | ||
|
|
aa0afa8d94 | ||
|
|
18e0031e0e | ||
|
|
a5018c110c | ||
|
|
142deb83b2 | ||
|
|
ccc0188352 | ||
|
|
98dba83107 | ||
|
|
9c6aff9030 | ||
|
|
7fd9a94922 | ||
|
|
dd3b1f3aed | ||
|
|
f9dce592e8 | ||
|
|
c4b0967623 | ||
|
|
41613061d5 | ||
|
|
50ef63e27d | ||
|
|
3ae4a35d04 | ||
|
|
89ea0ee15a | ||
|
|
85399e23ed | ||
|
|
19a6f218e6 | ||
|
|
ccaf290b63 | ||
|
|
54745d512c | ||
|
|
39234d4722 | ||
|
|
4b4310265b | ||
|
|
d8a982bf07 | ||
|
|
0334a6f02b | ||
|
|
ae0c613b8e | ||
|
|
40b2560752 | ||
|
|
50c6e51393 | ||
|
|
1434e00712 | ||
|
|
76c941cff0 | ||
|
|
bb03f31a8b | ||
|
|
c939b26cb8 | ||
|
|
af480efa8c | ||
|
|
bc913d70b1 | ||
|
|
2bc87d8a6b | ||
|
|
2185c48eab | ||
|
|
59b5046a15 | ||
|
|
569902b528 | ||
|
|
78519088ab | ||
|
|
0c06cdb29f | ||
|
|
7ac6816532 | ||
|
|
81c4216699 | ||
|
|
2e30389703 | ||
|
|
0e1d5cf04b | ||
|
|
4e2d84e4fc | ||
|
|
e8b8ff8927 | ||
|
|
13ee045b99 | ||
|
|
06bd407a0c | ||
|
|
aa28479d11 | ||
|
|
bf7db0ded2 | ||
|
|
dd1cbf2ee3 | ||
|
|
9d5db895c9 | ||
|
|
f1fd4c876b | ||
|
|
cd63b2b18f | ||
|
|
bab9b4a6b3 | ||
|
|
b3c34578bf | ||
|
|
f26477904e | ||
|
|
6b09da6e6e | ||
|
|
b2b6710a1b | ||
|
|
e7ee2ed7cf | ||
|
|
85886cf618 | ||
|
|
a19a861552 | ||
|
|
1dfd1ec1d3 | ||
|
|
96d57a6d24 | ||
|
|
b48155c249 | ||
|
|
41685022c0 | ||
|
|
2e8834a2c1 | ||
|
|
df098392c2 | ||
|
|
4e7274ce05 | ||
|
|
2384b0e51f | ||
|
|
6b6b938d1e | ||
|
|
29d8987909 | ||
|
|
43fb3f1a06 | ||
|
|
34c28fece3 | ||
|
|
40c2402493 | ||
|
|
c965e79bfc | ||
|
|
eeadb1fecb | ||
|
|
5e318a78d2 | ||
|
|
d872d64fe0 | ||
|
|
c2257493a8 | ||
|
|
48c1f8ffad | ||
|
|
8a4c8218d2 | ||
|
|
92e1321d43 | ||
|
|
43fb907a81 | ||
|
|
f551c56921 | ||
|
|
85e1f711f5 | ||
|
|
ade567a620 | ||
|
|
a26e519a3f | ||
|
|
797e47363f | ||
|
|
20e1836eb7 | ||
|
|
5ae746a1f0 | ||
|
|
17d271190b | ||
|
|
310f8bd1e1 | ||
|
|
bf7a4e729f | ||
|
|
1dd826f050 | ||
|
|
8b04aa5f31 | ||
|
|
6855fe0bce | ||
|
|
300be9e3dc | ||
|
|
384be2e2e9 | ||
|
|
1d71a0ad3a | ||
|
|
0e0ed316f1 | ||
|
|
8d0ff28304 | ||
|
|
cee9bb538f | ||
|
|
eb59d02a08 | ||
|
|
10ed71a3a2 | ||
|
|
0e86244559 | ||
|
|
5ab150cad3 | ||
|
|
3546afe86c | ||
|
|
961eedda04 | ||
|
|
f4881d2f49 | ||
|
|
a3eb269bdb | ||
|
|
e367123070 | ||
|
|
0f1d3fb553 | ||
|
|
a4658b2341 | ||
|
|
739113ef9e | ||
|
|
1629b861cd | ||
|
|
acce85557f | ||
|
|
05aefbaa62 | ||
|
|
6988fdc451 | ||
|
|
5963830879 | ||
|
|
134aded4d8 | ||
|
|
35780d9dc1 | ||
|
|
c40ac9bb9b | ||
|
|
51bd974cc9 | ||
|
|
0b93fbffd9 | ||
|
|
349f8b6c97 | ||
|
|
70077a6010 | ||
|
|
efdf36a817 | ||
|
|
e233788f69 | ||
|
|
957e6356f6 | ||
|
|
887eaa528a | ||
|
|
33126570bd | ||
|
|
5937183af0 | ||
|
|
5899921054 | ||
|
|
ec19014578 | ||
|
|
1ad990ce9d | ||
|
|
4eaa0a39d5 | ||
|
|
18ec73839b | ||
|
|
89aef977a2 | ||
|
|
2612569500 | ||
|
|
acc8b59387 | ||
|
|
2878d389c8 | ||
|
|
3f8effb7a3 | ||
|
|
bd30855ae6 | ||
|
|
0efe2f57c3 | ||
|
|
8868fcabed | ||
|
|
dfbb9e30e0 | ||
|
|
b22be7cade | ||
|
|
87da6c6816 | ||
|
|
912f7052a3 | ||
|
|
e6f9b0954c | ||
|
|
98e861cf3b | ||
|
|
43e0ca7edf | ||
|
|
d491bea263 | ||
|
|
6f1feb96d6 | ||
|
|
d46d12f949 | ||
|
|
c6fc92a94c | ||
|
|
f4fa790b72 | ||
|
|
22798fd750 | ||
|
|
907df56f86 | ||
|
|
3dadfa234b | ||
|
|
f1d7154179 | ||
|
|
dc47b9ce98 | ||
|
|
6e626851cf | ||
|
|
c906d8aea7 | ||
|
|
e5e4e09308 | ||
|
|
7ed173849a | ||
|
|
24c0d95112 | ||
|
|
e9fed34729 | ||
|
|
9caefdb67d | ||
|
|
681d5b6bdf | ||
|
|
b0e9758e0d | ||
|
|
7b9a8a55e7 | ||
|
|
44ac82e8b8 | ||
|
|
c4b4cb1173 | ||
|
|
30d798366b | ||
|
|
3e9a2b5c59 | ||
|
|
1343683b08 |
2
.github/workflows/codecov.yml
vendored
2
.github/workflows/codecov.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
fetch-depth: 2
|
||||
- uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: "1.16"
|
||||
go-version: "1.18"
|
||||
- name: Run coverage
|
||||
run: go test -v ./... -coverprofile=coverage.txt -covermode=atomic
|
||||
- name: Upload coverage to Codecov
|
||||
|
||||
801
README.md
801
README.md
@@ -1,31 +1,43 @@
|
||||
# Lancet
|
||||
<p style="font-size: 18px">
|
||||
Lancet is a comprehensive, efficient, and reusable util function library of go. Inspired by the java apache common package and lodash.js.
|
||||
</p>
|
||||
<div align=center>
|
||||
<img src="./logo.png" width="200" height="200"/>
|
||||
|
||||
<br/>
|
||||
|
||||

|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://pkg.go.dev/github.com/duke-git/lancet)
|
||||
[](https://goreportcard.com/report/github.com/duke-git/lancet)
|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://pkg.go.dev/github.com/duke-git/lancet/v2)
|
||||
[](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
|
||||
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
||||
[](https://codecov.io/gh/duke-git/lancet)
|
||||
[](https://github.com/duke-git/lancet/blob/main/LICENSE)
|
||||
</div>
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
<p style="font-size: 20px">
|
||||
Lancet is a comprehensive, efficient, and reusable util function library of go. Inspired by the java apache common package and lodash.js.
|
||||
</p>
|
||||
|
||||
English | [简体中文](./README_zh-CN.md)
|
||||
|
||||
|
||||
## Feature
|
||||
|
||||
- 👏 Comprehensive, efficient and reusable.
|
||||
- 💪 160+ common go util functions, support string, slice, datetime, net, crypt...
|
||||
- 💪 250+ go util functions, support string, slice, datetime, net, crypt...
|
||||
- 💅 Only depend on the go standard library.
|
||||
- 🌍 Unit test for every exported function.
|
||||
|
||||
## Installation
|
||||
### Note:
|
||||
|
||||
1. <b>For users who use go1.18 and above, it is recommended to install lancet v2.x.x. Cause v2.x.x rewrite all functions with generics of go1.18.</b>
|
||||
```go
|
||||
go get github.com/duke-git/lancet
|
||||
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. now latest v1 is v1.2.7. </b>
|
||||
```go
|
||||
go get github.com/duke-git/lancet@v1.2.7 // below go1.18, install latest version of v1.x.x
|
||||
```
|
||||
|
||||
## Usage
|
||||
@@ -33,7 +45,7 @@ go get github.com/duke-git/lancet
|
||||
Lancet organizes the code into package structure, and you need to import the corresponding package name when use it. For example, if you use string-related functions,import the strutil package like below:
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/strutil"
|
||||
import "github.com/duke-git/lancet/v2/strutil"
|
||||
```
|
||||
|
||||
## Example
|
||||
@@ -45,7 +57,7 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/strutil"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -56,541 +68,362 @@ func main() {
|
||||
```
|
||||
|
||||
## API Documentation
|
||||
### 1. convertor contains some functions for data convertion
|
||||
|
||||
- Support conversion between commonly used data types.
|
||||
- Usage: import "github.com/duke-git/lancet/convertor"
|
||||
### Algorithm package implements some basic algorithm. eg. sort, search.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s := "12.3"
|
||||
f, err := convertor.ToFloat(s)
|
||||
if err != nil {
|
||||
fmt.Errorf("error is %s", err.Error())
|
||||
}
|
||||
fmt.Println(f) // 12.3
|
||||
}
|
||||
import "github.com/duke-git/lancet/v2/algorithm"
|
||||
```
|
||||
#### Function list:
|
||||
- [BubbleSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#BubbleSort)
|
||||
- [CountSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#CountSort)
|
||||
- [HeapSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#HeapSort)
|
||||
- [InsertionSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#InsertionSort)
|
||||
- [MergeSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#MergeSort)
|
||||
- [QuickSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#QuickSort)
|
||||
- [SelectionSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#SelectionSort)
|
||||
- [ShellSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#ShellSort)
|
||||
- [BinarySearch](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#BinarySearch)
|
||||
- [BinaryIterativeSearch](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#BinaryIterativeSearch)
|
||||
- [LinearSearch](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#LinearSearch)
|
||||
- [LRUCache](https://github.com/duke-git/lancet/blob/main/docs/algorithm.md#LRUCache)
|
||||
|
||||
- Function list:
|
||||
|
||||
### Convertor package contains some functions for data convertion.
|
||||
|
||||
```go
|
||||
func ColorHexToRGB(colorHex string) (red, green, blue int) //convert color hex to color rgb
|
||||
func ColorRGBToHex(red, green, blue int) string //convert color rgb to color hex
|
||||
func ToBool(s string) (bool, error) //convert string to a boolean
|
||||
func ToBytes(data interface{}) ([]byte, error) //convert interface to bytes
|
||||
func ToChar(s string) []string //convert string to char slice
|
||||
func ToFloat(value interface{}) (float64, error) //convert value to float64, if input is not a float return 0.0 and error
|
||||
func ToInt(value interface{}) (int64, error) //convert value to int64, if input is not a numeric format return 0 and error
|
||||
func ToJson(value interface{}) (string, error) //convert value to a valid json string
|
||||
func ToString(value interface{}) string //convert value to string
|
||||
func StructToMap(value interface{}) (map[string]interface{}, error) //convert struct to map, only convert exported field, tag `json` should be set
|
||||
import "github.com/duke-git/lancet/v2/convertor"
|
||||
```
|
||||
|
||||
### 2. cryptor is for data encryption and decryption
|
||||
|
||||
- Support md5, hmac, aes, des, ras.
|
||||
- Usage: import "github.com/duke-git/lancet/cryptor"
|
||||
#### Function list:
|
||||
- [ColorHexToRGB](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ColorHexToRGB)
|
||||
- [ColorRGBToHex](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ColorRGBToHex)
|
||||
- [ToBool](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToBool)
|
||||
- [ToBytes](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToBytes)
|
||||
- [ToChar](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToChar)
|
||||
- [ToInt](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToInt)
|
||||
- [ToJson](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToJson)
|
||||
- [ToString](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToString)
|
||||
- [StructToMap](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#StructToMap)
|
||||
|
||||
### Cryptor package is for data encryption and decryption.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/cryptor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := "hello"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
|
||||
decrypted := cryptor.AesCbcDecrypt(encrypted, []byte(key))
|
||||
fmt.Println(string(decrypted)) // hello
|
||||
}
|
||||
import "github.com/duke-git/lancet/v2/cryptor"
|
||||
```
|
||||
|
||||
- Function list:
|
||||
#### Function list:
|
||||
- [AesEcbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesEcbEncrypt)
|
||||
- [AesEcbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesEcbDecrypt)
|
||||
- [AesCbcEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCbcEncrypt)
|
||||
- [AesCbcDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCbcDecrypt)
|
||||
- [AesCtrCrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCtrCrypt)
|
||||
- [AesCfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCfbEncrypt)
|
||||
- [AesCfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCfbDecrypt)
|
||||
- [AesOfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesOfbEncrypt)
|
||||
- [AesOfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesOfbDecrypt)
|
||||
- [Base64StdEncode](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Base64StdEncode)
|
||||
- [Base64StdDecode](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Base64StdDecode)
|
||||
- [DesEcbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesEcbEncrypt)
|
||||
- [DesEcbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesEcbDecrypt)
|
||||
- [DesCbcEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCbcEncrypt)
|
||||
- [DesCbcDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCbcDecrypt)
|
||||
- [DesCtrCrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCtrCrypt)
|
||||
- [DesCfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCfbEncrypt)
|
||||
- [DesCfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCfbDecrypt)
|
||||
- [DesOfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesOfbEncrypt)
|
||||
- [DesOfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesOfbDecrypt)
|
||||
- [HmacMd5](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#HmacMd5)
|
||||
- [HmacSha1](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#HmacSha1)
|
||||
- [HmacSha256](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#HmacSha256)
|
||||
- [HmacSha512](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#HmacSha512)
|
||||
- [Md5String](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Md5String)
|
||||
- [Md5File](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Md5File)
|
||||
- [Sha1](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Sha1)
|
||||
- [Sha256](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Sha256)
|
||||
- [Sha512](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Sha512)
|
||||
- [GenerateRsaKey](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#GenerateRsaKey)
|
||||
- [RsaEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#RsaEncrypt)
|
||||
- [RsaDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#RsaDecrypt)
|
||||
|
||||
### Datetime package supports date and time format and compare.
|
||||
|
||||
|
||||
```go
|
||||
func AesEcbEncrypt(data, key []byte) []byte //AES ECB encrypt
|
||||
func AesEcbDecrypt(encrypted, key []byte) []byte //AES ECB decrypt
|
||||
func AesCbcEncrypt(data, key []byte) []byte //AES CBC encrypt
|
||||
func AesCbcDecrypt(encrypted, key []byte) []byte //AES CBC decrypt
|
||||
func AesCtrCrypt(data, key []byte) []byte //AES CTR encrypt / decrypt
|
||||
func AesCfbEncrypt(data, key []byte) []byte //AES CFB encrypt
|
||||
func AesCfbDecrypt(encrypted, key []byte) []byte //AES CFB decrypt
|
||||
func AesOfbEncrypt(data, key []byte) []byte //AES OFB encrypt
|
||||
func AesOfbDecrypt(data, key []byte) []byte //AES OFB decrypt
|
||||
func Base64StdEncode(s string) string //base64 encode
|
||||
func Base64StdDecode(s string) string //base64 decode
|
||||
func DesCbcEncrypt(data, key []byte) []byte //DES CBC encrypt
|
||||
func DesCbcDecrypt(encrypted, key []byte) []byte //DES CBC decrypt
|
||||
func DesCtrCrypt(data, key []byte) []byte //DES CTR encrypt/decrypt
|
||||
func DesCfbEncrypt(data, key []byte) []byte //DES CFB encrypt
|
||||
func DesCfbDecrypt(encrypted, key []byte) []byte //DES CFB decrypt
|
||||
func DesOfbEncrypt(data, key []byte) []byte //DES OFB encrypt
|
||||
func DesOfbDecrypt(data, key []byte) []byte //DES OFB decrypt
|
||||
func HmacMd5(data, key string) string //get hmac md5 value
|
||||
func HmacSha1(data, key string) string //get hmac sha1 value
|
||||
func HmacSha256(data, key string) string //get hmac sha256 value
|
||||
func HmacSha512(data, key string) string //get hmac sha512 value
|
||||
func Md5String(s string) string //return the md5 value of string
|
||||
func Md5File(filename string) (string, error) //return the md5 value of file
|
||||
func Sha1(data string) string //get sha1 value
|
||||
func Sha256(data string) string //getsha256 value
|
||||
func Sha512(data string) string //get sha512 value
|
||||
func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) //generate RSA pem file
|
||||
func RsaEncrypt(data []byte, pubKeyFileName string) []byte //RSA encrypt
|
||||
func RsaDecrypt(data []byte, privateKeyFileName string) []byte //RSA decrypt
|
||||
|
||||
import "github.com/duke-git/lancet/v2/datetime"
|
||||
```
|
||||
#### Function list:
|
||||
- [AddDay](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#AddDay)
|
||||
- [AddHour](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#AddHour)
|
||||
- [AddMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#AddMinute)
|
||||
- [BeginOfMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfMinute)
|
||||
- [BeginOfHour](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfHour)
|
||||
- [BeginOfDay](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfDay)
|
||||
- [BeginOfWeek](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfWeek)
|
||||
- [BeginOfMonth](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfMonth)
|
||||
- [BeginOfYear](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfYear)
|
||||
- [EndOfMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfMinute)
|
||||
- [EndOfHour](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfHour)
|
||||
- [EndOfDay](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfDay)
|
||||
- [EndOfWeek](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfWeek)
|
||||
- [EndOfMonth](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfMonth)
|
||||
- [EndOfYear](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfYear)
|
||||
- [GetNowDate](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetNowDate)
|
||||
- [GetNowTime](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetNowTime)
|
||||
- [GetNowDateTime](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetNowDateTime)
|
||||
- [GetZeroHourTimestamp](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetZeroHourTimestamp)
|
||||
- [GetNightTimestamp](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetNightTimestamp)
|
||||
- [FormatTimeToStr](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#FormatTimeToStr)
|
||||
- [FormatStrToTime](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#FormatStrToTime)
|
||||
- [NewUnix](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#NewUnix)
|
||||
- [NewUnixNow](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#NewUnixNow)
|
||||
- [NewFormat](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#NewFormat)
|
||||
- [NewISO8601](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#NewISO8601)
|
||||
- [ToUnix](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#ToUnix)
|
||||
- [ToFormat](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#ToFormat)
|
||||
- [ToFormatForTpl](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#ToFormatForTpl)
|
||||
- [ToIso8601](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#ToIso8601)
|
||||
|
||||
### 3. datetime parse and format datetime
|
||||
|
||||
- Parse and format datetime
|
||||
- Usage: import "github.com/duke-git/lancet/datetime"
|
||||
### Fileutil package implements some basic functions for file operations.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
s := datetime.FormatTimeToStr(now, "yyyy-mm-dd hh:mm:ss")
|
||||
fmt.Println(s) // 2021-11-24 11:16:55
|
||||
}
|
||||
import "github.com/duke-git/lancet/v2/fileutil"
|
||||
```
|
||||
|
||||
- Function list:
|
||||
#### Function list:
|
||||
|
||||
- [ClearFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#ClearFile)
|
||||
- [CreateFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#CreateFile)
|
||||
- [CopyFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#CopyFile)
|
||||
- [FileMode](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#FileMode)
|
||||
- [MiMeType](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#MiMeType)
|
||||
- [IsExist](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#IsExist)
|
||||
- [IsLink](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#IsLink)
|
||||
- [IsDir](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#IsDir)
|
||||
- [ListFileNames](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#ListFileNames)
|
||||
- [RemoveFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#RemoveFile)
|
||||
- [ReadFileToString](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#ReadFileToString)
|
||||
- [ReadFileByLine](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#ReadFileByLine)
|
||||
- [Zip](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#Zip)
|
||||
- [UnZip](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#UnZip)
|
||||
|
||||
### Formatter contains some functions for data formatting.
|
||||
|
||||
```go
|
||||
func AddDay(t time.Time, day int64) time.Time //add or sub days to time
|
||||
func AddHour(t time.Time, hour int64) time.Time //add or sub hours to time
|
||||
func AddMinute(t time.Time, minute int64) time.Time //add or sub minutes to time
|
||||
func GetNowDate() string //get current date, format is yyyy-mm-dd
|
||||
func GetNowTime() string //get current time, format is hh:mm:ss
|
||||
func GetNowDateTime() string //get current date and time, format is yyyy-mm-dd hh:mm:ss
|
||||
func GetZeroHourTimestamp() int64 //return timestamp of zero hour (timestamp of 00:00)
|
||||
func GetNightTimestamp() int64 //return timestamp of zero hour (timestamp of 23:59)
|
||||
func FormatTimeToStr(t time.Time, format string) string //convert time to string
|
||||
func FormatStrToTime(str, format string) time.Time //convert string to time
|
||||
import "github.com/duke-git/lancet/v2/formatter"
|
||||
```
|
||||
#### Function list:
|
||||
- [Comma](https://github.com/duke-git/lancet/blob/main/docs/formatter.md#Comma)
|
||||
|
||||
### 4. fileutil basic functions for file operations
|
||||
|
||||
- Basic functions for file operations.
|
||||
- Usage: import "github.com/duke-git/lancet/fileutil"
|
||||
### Function package can control the flow of function execution and support part of functional programming
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(fileutil.IsDir("./")) // true
|
||||
}
|
||||
import "github.com/duke-git/lancet/v2/function"
|
||||
```
|
||||
|
||||
- Function list:
|
||||
#### Function list:
|
||||
- [After](https://github.com/duke-git/lancet/blob/main/docs/function.md#After)
|
||||
- [Before](https://github.com/duke-git/lancet/blob/main/docs/function.md#Before)
|
||||
- [Curry](https://github.com/duke-git/lancet/blob/main/docs/function.md#Curry)
|
||||
- [Compose](https://github.com/duke-git/lancet/blob/main/docs/function.md#Compose)
|
||||
- [Debounced](https://github.com/duke-git/lancet/blob/main/docs/function.md#Debounced)
|
||||
- [Delay](https://github.com/duke-git/lancet/blob/main/docs/function.md#Delay)
|
||||
- [Watcher](https://github.com/duke-git/lancet/blob/main/docs/function.md#Watcher)
|
||||
|
||||
|
||||
### Mathutil package implements some functions for math calculation.
|
||||
|
||||
```go
|
||||
func ClearFile(path string) error //write empty string to path file
|
||||
func CreateFile(path string) bool // create a file in path
|
||||
func CopyFile(srcFilePath string, dstFilePath string) error //copy src file to dst file
|
||||
func FileMode(path string) (fs.FileMode, error) //return file's mode and permission
|
||||
func MiMeType(file interface{}) string //return file mime type, file should be string or *os.File
|
||||
func IsExist(path string) bool //checks if a file or directory exists
|
||||
func IsLink(path string) bool //checks if a file is symbol link or not
|
||||
func IsDir(path string) bool //checks if the path is directy or not
|
||||
func ListFileNames(path string) ([]string, error) //return all file names in the path
|
||||
func RemoveFile(path string) error //remove the path file
|
||||
func ReadFileToString(path string) (string, error) //return string of file content
|
||||
func ReadFileByLine(path string)([]string, error) //read file content by line
|
||||
func Zip(fpath string, destPath string) error //create zip file, fpath could be a single file or a directory
|
||||
func UnZip(zipFile string, destPath string) error //unzip the file and save it to destPath
|
||||
import "github.com/duke-git/lancet/v2/mathutil"
|
||||
```
|
||||
|
||||
### 5. formatter is for data format
|
||||
#### Function list:
|
||||
- [Average](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Average)
|
||||
- [Exponent](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Exponent)
|
||||
- [Fibonacci](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Fibonacci)
|
||||
- [Factorial](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Factorial)
|
||||
- [Max](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Max)
|
||||
- [Min](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Min)
|
||||
- [Percent](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Percent)
|
||||
- [RoundToFloat](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#RoundToFloat)
|
||||
- [RoundToString](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#RoundToString)
|
||||
- [TruncRound](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#TruncRound)
|
||||
|
||||
- Contain some formatting function
|
||||
- Usage: import "github.com/duke-git/lancet/formatter"
|
||||
|
||||
### Netutil package contains functions to get net information and send http request.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/formatter"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(formatter.Comma("12345", "")) // "12,345"
|
||||
fmt.Println(formatter.Comma(12345.67, "¥")) // "¥12,345.67"
|
||||
}
|
||||
import "github.com/duke-git/lancet/v2/netutil"
|
||||
```
|
||||
|
||||
- Function list:
|
||||
#### Function list:
|
||||
- [ConvertMapToQueryString](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#ConvertMapToQueryString)
|
||||
- [GetInternalIp](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetInternalIp)
|
||||
- [GetIps](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetIps)
|
||||
- [GetMacAddrs](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetMacAddrs)
|
||||
- [GetPublicIpInfo](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetPublicIpInfo)
|
||||
- [IsPublicIP](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#IsPublicIP)
|
||||
- [HttpGet](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpGet)
|
||||
- [HttpDelete](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpDelete)
|
||||
- [HttpPost](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPost)
|
||||
- [HttpPut](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPut)
|
||||
- [HttpPatch](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPatch)
|
||||
- [ParseHttpResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#ParseHttpResponse)
|
||||
|
||||
### Random package implements some basic functions to generate random int and string.
|
||||
|
||||
```go
|
||||
func Comma(v interface{}, symbol string) string //add comma to number by every 3 numbers from right. ahead by symbol char
|
||||
import "github.com/duke-git/lancet/v2/random"
|
||||
```
|
||||
|
||||
### 6. function can control the function execution and support functional programming
|
||||
#### Function list:
|
||||
- [RandBytes](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandBytes)
|
||||
- [RandInt](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandInt)
|
||||
- [RandString](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandString)
|
||||
- [UUIdV4](https://github.com/duke-git/lancet/blob/main/docs/random.md#UUIdV4)
|
||||
|
||||
- Control function execution and support functional programming.
|
||||
- Usage: import "github.com/duke-git/lancet/function"
|
||||
### Retry package is for executing a function repeatedly until it was successful or canceled by the context.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/function"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var print = func(s string) {
|
||||
fmt.Println(s)
|
||||
}
|
||||
function.Delay(2*time.Second, print, "hello world")
|
||||
}
|
||||
import "github.com/duke-git/lancet/v2/retry"
|
||||
```
|
||||
|
||||
- Function list:
|
||||
#### Function list:
|
||||
- [Context](https://github.com/duke-git/lancet/blob/main/docs/retry.md#Context)
|
||||
- [Retry](https://github.com/duke-git/lancet/blob/main/docs/retry.md#Retry)
|
||||
- [RetryFunc](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryFunc)
|
||||
- [RetryDuration](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryDuration)
|
||||
- [RetryTimes](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryTimes)
|
||||
|
||||
### Slice contains some functions to manipulate slice.
|
||||
|
||||
```go
|
||||
func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value //creates a function that invokes func once it's called n or more times
|
||||
func Before(n int, fn interface{}) func(args ...interface{}) []reflect.Value //creates a function that invokes func once it's called less than n times
|
||||
func (f Fn) Curry(i interface{}) func(...interface{}) interface{} //make a curryed function
|
||||
func Compose(fnList ...func(...interface{}) interface{}) func(...interface{}) interface{} //compose the functions from right to left
|
||||
func Debounced(fn func(), duration time.Duration) func() //creates a debounced function that delays invoking fn until after wait duration have elapsed since the last time the debounced function was invoked.
|
||||
func Delay(delay time.Duration, fn interface{}, args ...interface{}) //invoke function after delayed time
|
||||
func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool //invoke function every duration time, util close the returned bool chan
|
||||
func (w *Watcher) Start() //start the watch timer.
|
||||
func (w *Watcher) Stop() //stop the watch timer
|
||||
func (w *Watcher) Reset() {} //reset the watch timer.
|
||||
func (w *Watcher) GetElapsedTime() time.Duration //return time duration from watcher start to end.
|
||||
import "github.com/duke-git/lancet/v2/slice"
|
||||
```
|
||||
|
||||
### 7. netutil is for net process
|
||||
#### Function list:
|
||||
- [Contain](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Contain)
|
||||
- [ContainSubSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ContainSubSlice)
|
||||
- [Chunk](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Chunk)
|
||||
- [Compact](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Compact)
|
||||
- [Concat](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Concat)
|
||||
- [Count](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Count)
|
||||
- [Difference](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Difference)
|
||||
- [DifferenceBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DifferenceBy)
|
||||
- [DifferenceWith](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DifferenceWith)
|
||||
- [DeleteAt](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DeleteAt)
|
||||
- [Drop](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Drop)
|
||||
- [Every](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Every)
|
||||
- [Filter](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Filter)
|
||||
- [Find](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Find)
|
||||
- [FindLast](https://github.com/duke-git/lancet/blob/main/docs/slice.md#FindLast)
|
||||
- [FlattenDeep](#FlattenDeep)
|
||||
- [ForEach](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ForEach)
|
||||
- [GroupBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#GroupBy)
|
||||
- [GroupWith](https://github.com/duke-git/lancet/blob/main/docs/slice.md#GroupWith)
|
||||
- [IntSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#IntSlice)
|
||||
- [InterfaceSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#InterfaceSlice)
|
||||
- [Intersection](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Intersection)
|
||||
- [InsertAt](https://github.com/duke-git/lancet/blob/main/docs/slice.md#InsertAt)
|
||||
- [Map](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Map)
|
||||
- [Reverse](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Reverse)
|
||||
- [Reduce](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Reduce)
|
||||
- [Shuffle](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Shuffle)
|
||||
- [SortByField](https://github.com/duke-git/lancet/blob/main/docs/slice.md#SortByField)
|
||||
- [Some](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Some)
|
||||
- [StringSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#StringSlice)
|
||||
- [Unique](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Unique)
|
||||
- [Union](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Union)
|
||||
- [UpdateAt](https://github.com/duke-git/lancet/blob/main/docs/slice.md#UpdateAt)
|
||||
- [Without](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Without)
|
||||
|
||||
- Ip and http request method.
|
||||
- Usage: import "github.com/duke-git/lancet/netutil".
|
||||
- The Http function params order:url, header, query string, body, httpclient.
|
||||
### Strutil package contains some functions to manipulate string.
|
||||
```go
|
||||
import "github.com/duke-git/lancet/v2/strutil"
|
||||
```
|
||||
|
||||
#### Function list:
|
||||
|
||||
- [After](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#After)
|
||||
- [AfterLast](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#AfterLast)
|
||||
- [Before](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Before)
|
||||
- [BeforeLast](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#BeforeLast)
|
||||
- [CamelCase](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#CamelCase)
|
||||
- [Capitalize](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Capitalize)
|
||||
- [IsString](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#IsString)
|
||||
- [KebabCase](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#KebabCase)
|
||||
- [LowerFirst](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#LowerFirst)
|
||||
- [UpperFirst](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#UpperFirst)
|
||||
- [PadEnd](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#PadEnd)
|
||||
- [PadStart](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#PadStart)
|
||||
- [ReverseStr](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#ReverseStr)
|
||||
- [SnakeCase](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#SnakeCase)
|
||||
- [Wrap](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Wrap)
|
||||
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Unwrap)
|
||||
|
||||
### System package contain some functions about os, runtime, shell command.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
url := "https://gutendex.com/books?"
|
||||
header := make(map[string]string)
|
||||
header["Content-Type"] = "application/json"
|
||||
queryParams := make(map[string]interface{})
|
||||
queryParams["ids"] = "1"
|
||||
|
||||
resp, err := netutil.HttpGet(url, header, queryParams)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
fmt.Println("response: ", resp.StatusCode, string(body))
|
||||
}
|
||||
import "github.com/duke-git/lancet/v2/system"
|
||||
```
|
||||
#### Function list:
|
||||
- [IsWindows](https://github.com/duke-git/lancet/blob/main/docs/system.md#IsWindows)
|
||||
- [IsLinux](https://github.com/duke-git/lancet/blob/main/docs/system.md#IsLinux)
|
||||
- [IsMac](https://github.com/duke-git/lancet/blob/main/docs/system.md#IsMac)
|
||||
- [GetOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system.md#GetOsEnv)
|
||||
- [SetOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system.md#SetOsEnv)
|
||||
- [RemoveOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system.md#RemoveOsEnv)
|
||||
- [CompareOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system.md#CompareOsEnv)
|
||||
- [ExecCommand](https://github.com/duke-git/lancet/blob/main/docs/system.md#ExecCommand)
|
||||
|
||||
- Function list:
|
||||
### Validator package contains some functions for data validation.
|
||||
|
||||
```go
|
||||
func GetInternalIp() string //get internal ip
|
||||
func GetPublicIpInfo() (*PublicIpInfo, error) //get public ip info: country, region, isp, city, lat, lon, ip
|
||||
func IsPublicIP(IP net.IP) bool //判断ip是否为公共ip
|
||||
func HttpGet(url string, params ...interface{}) (*http.Response, error) //http get request
|
||||
func HttpPost(url string, params ...interface{}) (*http.Response, error) //http post request
|
||||
func HttpPut(url string, params ...interface{}) (*http.Response, error) //http put request
|
||||
func HttpDelete(url string, params ...interface{}) (*http.Response, error) //http delete request
|
||||
func HttpPatch(url string, params ...interface{}) (*http.Response, error) //http patch request
|
||||
func ConvertMapToQueryString(param map[string]interface{}) string //convert map to url query string
|
||||
func ParseHttpResponse(resp *http.Response, obj interface{}) error //decode http response to specified interface
|
||||
import "github.com/duke-git/lancet/v2/validator"
|
||||
```
|
||||
|
||||
### 8. random is for rand string and int generation
|
||||
#### Function list:
|
||||
|
||||
- Generate random string and int.
|
||||
- Usage: import "github.com/duke-git/lancet/random".
|
||||
- [ContainChinese](https://github.com/duke-git/lancet/blob/main/docs/validator.md#ContainChinese)
|
||||
- [ContainLetter](https://github.com/duke-git/lancet/blob/main/docs/validator.md#ContainLetter)
|
||||
- [ContainLower](https://github.com/duke-git/lancet/blob/main/docs/validator.md#ContainLower)
|
||||
- [ContainUpper](https://github.com/duke-git/lancet/blob/main/docs/validator.md#ContainUpper)
|
||||
- [IsAlpha](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsAlpha)
|
||||
- [IsAllUpper](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsAllUpper)
|
||||
- [IsAllLower](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsAllLower)
|
||||
- [IsBase64](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsBase64)
|
||||
- [IsChineseMobile](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsChineseMobile)
|
||||
- [IsChineseIdNum](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsChineseIdNum)
|
||||
- [IsChinesePhone](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsChinesePhone)
|
||||
- [IsCreditCard](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsCreditCard)
|
||||
- [IsDns](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsDns)
|
||||
- [IsEmail](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsEmail)
|
||||
- [IsEmptyString](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsEmptyString)
|
||||
- [IsFloatStr](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsFloatStr)
|
||||
- [IsNumberStr](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsNumberStr)
|
||||
- [IsJSON](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsJSON)
|
||||
- [IsRegexMatch](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsRegexMatch)
|
||||
- [IsIntStr](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsIntStr)
|
||||
- [IsIp](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsIp)
|
||||
- [IsIpV4](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsIpV4)
|
||||
- [IsIpV6](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsIpV6)
|
||||
- [IsStrongPassword](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsStrongPassword)
|
||||
- [IsUrl](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsUrl)
|
||||
- [IsWeakPassword](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsWeakPassword)
|
||||
### xerror package implements helpers for errors.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/random"
|
||||
)
|
||||
|
||||
func main() {
|
||||
randStr := random.RandString(6)
|
||||
fmt.Println(randStr)
|
||||
}
|
||||
import "github.com/duke-git/lancet/v2/xerror"
|
||||
```
|
||||
#### Function list:
|
||||
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/xerror.md#Unwrap)
|
||||
|
||||
|
||||
- Function list:
|
||||
## How to Contribute
|
||||
|
||||
```go
|
||||
func RandBytes(length int) []byte //generate random []byte
|
||||
func RandInt(min, max int) int //generate random int
|
||||
func RandString(length int) string //generate random string
|
||||
```
|
||||
I really appreciate any code commits which make lancet lib powerful. Please follow the rules below to create your pull request.
|
||||
|
||||
### 9. retry is for executing a function repeatedly until it was successful or canceled by the context.
|
||||
|
||||
- Executes a function repeatedly until it was successful or canceled by the context.
|
||||
- Default retry times is 5, default retry duration is 3 second.
|
||||
- Usage: import "github.com/duke-git/lancet/retry".
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/retry"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var number int
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
||||
|
||||
fmt.Println(number) //3
|
||||
}
|
||||
```
|
||||
|
||||
- Function list:
|
||||
|
||||
```go
|
||||
type RetryFunc func() error //function that retry executes
|
||||
func RetryTimes(n uint) //set times of retry
|
||||
func RetryDuration(d time.Duration) //generate random string
|
||||
func Context(ctx context.Context) //set retry context config
|
||||
func Retry(retryFunc RetryFunc, opts ...Option) error //executes the retryFunc repeatedly until it was successful or canceled by the context
|
||||
```
|
||||
|
||||
### 10. slice is for process slice
|
||||
|
||||
- Contain function for process slice.
|
||||
- Usage: import "github.com/duke-git/lancet/slice"
|
||||
- Due to the unstable support of generic, most of the slice processing function parameter and return value is interface {}. After go generic is stable, the related functions will be refactored.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/slice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
nums := []int{1, 4, 3, 4, 6, 7, 3}
|
||||
uniqueNums, _ := slice.IntSlice(slice.Unique(nums))
|
||||
fmt.Println(uniqueNums) //[1 4 3 6 7]
|
||||
}
|
||||
```
|
||||
|
||||
- Function list:
|
||||
|
||||
```go
|
||||
func Contain(slice interface{}, value interface{}) bool //check if the value is in the slice or not
|
||||
func ContainSubSlice(slice interface{}, subslice interface{}) bool //check if the slice contain subslice or not
|
||||
func Chunk(slice []interface{}, size int) [][]interface{} //creates an slice of elements split into groups the length of `size`
|
||||
func Compact(slice interface{}) interface{} //creates an slice with all falsey values removed. The values false, nil, 0, and "" are falsey
|
||||
func Concat(slice interface{}, values ...interface{}) interface{} //creates a new slice concatenating slice with any additional slices and/or values
|
||||
func Difference(slice1, slice2 interface{}) interface{} //creates an slice of whose element not included in the other given slice
|
||||
func DifferenceBy(slice interface{}, comparedSlice interface{}, iterateeFn interface{}) interface{} //it accepts iteratee which is invoked for each element of slice and values to generate the criterion by which they're compared.
|
||||
func DeleteByIndex(slice interface{}, start int, end ...int) (interface{}, error) //delete the element of slice from start index to end index - 1
|
||||
func Drop(slice interface{}, n int) interface{} //creates a slice with `n` elements dropped from the beginning when n > 0, or `n` elements dropped from the ending when n < 0
|
||||
func Every(slice, function interface{}) bool //return true if all of the values in the slice pass the predicate function, function signature should be func(index int, value interface{}) bool
|
||||
func None(slice, function interface{}) bool // return true if all the values in the slice mismatch the criteria
|
||||
func Filter(slice, function interface{}) interface{} //filter slice, function signature should be func(index int, value interface{}) bool
|
||||
func Find(slice, function interface{}) (interface{}, bool) //iterates over elements of slice, returning the first one that passes a truth test on function.function signature should be func(index int, value interface{}) bool
|
||||
func FlattenDeep(slice interface{}) interface{} //flattens slice recursive
|
||||
func ForEach(slice, function interface{}) //iterates over elements of slice and invokes function for each element, function signature should be func(index int, value interface{})
|
||||
func IntSlice(slice interface{}) ([]int, error) //convert value to int slice
|
||||
func InterfaceSlice(slice interface{}) []interface{} //convert value to interface{} slice
|
||||
func Intersection(slices ...interface{}) interface{} //creates a slice of unique values that included by all slices.
|
||||
func InsertByIndex(slice interface{}, index int, value interface{}) (interface{}, error) //insert the element into slice at index.
|
||||
func Map(slice, function interface{}) interface{} //map lisce, function signature should be func(index int, value interface{}) interface{}
|
||||
func ReverseSlice(slice interface{}) //revere slice
|
||||
func Reduce(slice, function, zero interface{}) interface{} //reduce slice, function signature should be func(index int, value1, value2 interface{}) interface{}
|
||||
func Shuffle(slice interface{}) interface{} //creates an slice of shuffled values
|
||||
func SortByField(slice interface{}, field string, sortType ...string) error //sort struct slice by field
|
||||
func Some(slice, function interface{}) bool //return true if any of the values in the list pass the predicate function, function signature should be func(index int, value interface{}) bool
|
||||
func StringSlice(slice interface{}) []string //convert value to string slice
|
||||
func Unique(slice interface{}) interface{} //remove duplicate elements in slice
|
||||
func Union(slices ...interface{}) interface{} //Union creates a slice of unique values, in order, from all given slices. using == for equality comparisons
|
||||
func UpdateByIndex(slice interface{}, index int, value interface{}) (interface{}, error) //update the slice element at index.
|
||||
func Without(slice interface{}, values ...interface{}) interface{} //creates a slice excluding all given values
|
||||
func GroupBy(slice, function interface{}) (interface{}, interface{}) // groups slice into two categories
|
||||
func Count(slice, function interface{}) int // Count iterates over elements of slice, returns a count of all matched elements
|
||||
```
|
||||
|
||||
### 11. strutil is for processing string
|
||||
|
||||
- Contain functions to precess string
|
||||
- Usage: import "github.com/duke-git/lancet/strutil"
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
str := "Foo-Bar"
|
||||
camelCaseStr := strutil.CamelCase(str)
|
||||
fmt.Println(camelCaseStr) //fooBar
|
||||
}
|
||||
```
|
||||
|
||||
- Function list:
|
||||
|
||||
```go
|
||||
func After(s, char string) string //create substring in source string after position when char first appear
|
||||
func AfterLast(s, char string) string //create substring in source string after position when char last appear
|
||||
func Before(s, char string) string //create substring in source string before position when char first appear
|
||||
func BeforeLast(s, char string) string //create substring in source string before position when char last appear
|
||||
func CamelCase(s string) string //covert string to camelCase string. "foo bar" -> "fooBar"
|
||||
func Capitalize(s string) string //convert the first character of a string to upper case, "fOO" -> "Foo"
|
||||
func IsString(v interface{}) bool //check if the value data type is string or not
|
||||
func KebabCase(s string) string //covert string to kebab-case, "foo_Bar" -> "foo-bar"
|
||||
func LowerFirst(s string) string //convert the first character of string to lower case
|
||||
func UpperFirst(s string) string //converts the first character of string to upper case
|
||||
func PadEnd(source string, size int, padStr string) string //pads string on the right side if it's shorter than size
|
||||
func PadStart(source string, size int, padStr string) string//pads string on the left side if it's shorter than size
|
||||
func ReverseStr(s string) string //return string whose char order is reversed to the given string
|
||||
func SnakeCase(s string) string //covert string to snake_case "fooBar" -> "foo_bar"
|
||||
func Wrap(str string, wrapWith string) string //wrap a string with another string.
|
||||
func Unwrap(str string, wrapToken string) string //unwrap a given string from anther string. will change str value
|
||||
```
|
||||
### 12. system contain some functions about os, runtime, shell command.
|
||||
|
||||
- Generate random string and int.
|
||||
- Usage: import "github.com/duke-git/lancet/system".
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
envFoo := system.GetOsEnv("foo")
|
||||
fmt.Println(envFoo)
|
||||
}
|
||||
```
|
||||
|
||||
- Function list:
|
||||
|
||||
```go
|
||||
func IsWindows() bool //check if current os is windows
|
||||
func IsLinux() bool //check if current os is linux
|
||||
func IsMac() bool //check if current os is macos
|
||||
func GetOsEnv(key string) string //gets the value of the environment variable named by the key.
|
||||
func SetOsEnv(key, value string) error //sets the value of the environment variable named by the key.
|
||||
func RemoveOsEnv(key string) error //remove a single environment variable.
|
||||
func CompareOsEnv(key, comparedEnv string) bool //gets env named by the key and compare it with comparedEnv
|
||||
func ExecCommand(command string) (stdout, stderr string, err error) //use shell /bin/bash -c to execute command
|
||||
```
|
||||
|
||||
### 13. validator is for data validation
|
||||
|
||||
- Contain function for data validation.
|
||||
- Usage: import "github.com/duke-git/lancet/validator".
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
str := "Foo-Bar"
|
||||
isAlpha := validator.IsAlpha(str)
|
||||
fmt.Println(isAlpha) //false
|
||||
}
|
||||
```
|
||||
|
||||
- Function list:
|
||||
|
||||
```go
|
||||
func ContainChinese(s string) bool //check if the string contain mandarin chinese
|
||||
func IsAlpha(s string) bool //checks if the string contains only letters (a-zA-Z)
|
||||
func IsBase64(base64 string) bool //check if the string is base64 string
|
||||
func IsAllUpper(str string) bool //check if the string is all upper case letters A-Z
|
||||
func IsAllLower(str string) bool //check if the string is all lower case letters a-z
|
||||
func ContainUpper(str string) bool //check if the string contain at least one upper case letter A-Z
|
||||
func ContainLower(str string) bool //check if the string contain at least one lower case letter a-z
|
||||
func ContainLetter(str string) bool //check if the string contain at least one letter
|
||||
func IsJSON(str string) bool //checks if the string is valid JSON
|
||||
func IsChineseMobile(mobileNum string) bool //check if the string is chinese mobile number
|
||||
func IsChineseIdNum(id string) bool //check if the string is chinese id number
|
||||
func IsChinesePhone(phone string) bool //check if the string is chinese phone number
|
||||
func IsCreditCard(creditCart string) bool //check if the string is credit card
|
||||
func IsDns(dns string) bool //check if the string is dns
|
||||
func IsEmail(email string) bool //check if the string is a email address
|
||||
func IsEmptyString(s string) bool //check if the string is empty
|
||||
func IsFloatStr(s string) bool //check if the string can convert to a float
|
||||
func IsNumberStr(s string) bool //check if the string can convert to a number
|
||||
func IsRegexMatch(s, regex string) bool //check if the string match the regexp
|
||||
func IsIntStr(s string) bool //check if the string can convert to a integer
|
||||
func IsIp(ipstr string) bool //check if the string is a ip address
|
||||
func IsIpV4(ipstr string) bool //check if the string is a ipv4 address
|
||||
func IsIpV6(ipstr string) bool //check if the string is a ipv6 address
|
||||
func IsStrongPassword(password string, length int) bool //check if the string is strong password (alpha(lower+upper) + number + special chars(!@#$%^&*()?><))
|
||||
func IsUrl(str string) bool //check if the string is url
|
||||
func IsWeakPassword(password string) bool //check if the string is weak password(only letter or only number or letter + number)
|
||||
```
|
||||
1. Fork the repository.
|
||||
2. Create your feature branch.
|
||||
3. Commit your changes.
|
||||
4. Push to the branch
|
||||
5. Create new pull request.
|
||||
|
||||
794
README_zh-CN.md
794
README_zh-CN.md
@@ -1,16 +1,21 @@
|
||||
# Lancet
|
||||
<p style="font-size: 18px">
|
||||
lancet(柳叶刀)是一个全面、高效、可复用的go语言工具函数库。 lancet受到了java apache common包和lodash.js的启发。
|
||||
</p>
|
||||
<div align=center>
|
||||
<img src="./logo.png" width="200" height="200"/>
|
||||
|
||||
<br/>
|
||||
|
||||

|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://pkg.go.dev/github.com/duke-git/lancet)
|
||||
[](https://goreportcard.com/report/github.com/duke-git/lancet)
|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://pkg.go.dev/github.com/duke-git/lancet/v2)
|
||||
[](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
|
||||
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
||||
[](https://codecov.io/gh/duke-git/lancet)
|
||||
[](https://github.com/duke-git/lancet/blob/main/LICENSE)
|
||||
</div>
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
<p style="font-size: 18px">
|
||||
lancet(柳叶刀)是一个全面、高效、可复用的go语言工具函数库。 lancet受到了java apache common包和lodash.js的启发。
|
||||
</p>
|
||||
|
||||
简体中文 | [English](./README.md)
|
||||
|
||||
@@ -18,14 +23,21 @@
|
||||
## 特性
|
||||
|
||||
- 👏 全面、高效、可复用
|
||||
- 💪 160+常用go工具函数,支持string、slice、datetime、net、crypt...
|
||||
- 💪 250+常用go工具函数,支持string、slice、datetime、net、crypt...
|
||||
- 💅 只依赖go标准库
|
||||
- 🌍 所有导出函数单元测试覆盖率100%
|
||||
|
||||
## 安装
|
||||
### Note:
|
||||
1. <b>对于使用go1.18及以上的用户,建议安装v2.x.x。 因为v2.x.x用go1.18的泛型重写了大部分函数。</b>
|
||||
|
||||
```go
|
||||
go get github.com/duke-git/lancet
|
||||
go get github.com/duke-git/lancet/v2 //安装v2最新版本v2.x.x
|
||||
```
|
||||
|
||||
2. <b>使用go1.18以下版本的用户,必须安装v1.x.x。目前最新的v1版本是v1.2.7。</b>
|
||||
```go
|
||||
go get github.com/duke-git/lancet@v1.2.7 // 使用go1.18以下版本, 必须安装v1.x.x版本
|
||||
```
|
||||
|
||||
## 用法
|
||||
@@ -33,7 +45,7 @@ go get github.com/duke-git/lancet
|
||||
lancet是以包的结构组织代码的,使用时需要导入相应的包名。例如:如果使用字符串相关函数,需要导入strutil包:
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/strutil"
|
||||
import "github.com/duke-git/lancet/v2/strutil"
|
||||
```
|
||||
|
||||
## 例子
|
||||
@@ -45,7 +57,7 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/strutil"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -56,542 +68,364 @@ func main() {
|
||||
```
|
||||
|
||||
## API文档
|
||||
### 1. convertor数据转换包
|
||||
|
||||
- 转换函数支持常用数据类型之间的转换
|
||||
- 导入包:import "github.com/duke-git/lancet/convertor"
|
||||
### algorithm算法包实现一些基本算法。eg. sort, search.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s := "12.3"
|
||||
f, err := convertor.ToFloat(s)
|
||||
if err != nil {
|
||||
fmt.Errorf("error is %s", err.Error())
|
||||
}
|
||||
fmt.Println(f) // 12.3
|
||||
}
|
||||
import "github.com/duke-git/lancet/v2/algorithm"
|
||||
```
|
||||
#### Function list:
|
||||
- [BubbleSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#BubbleSort)
|
||||
- [CountSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#CountSort)
|
||||
- [HeapSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#HeapSort)
|
||||
- [InsertionSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#InsertionSort)
|
||||
- [MergeSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#MergeSort)
|
||||
- [QuickSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#QuickSort)
|
||||
- [SelectionSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#SelectionSort)
|
||||
- [ShellSort](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#ShellSort)
|
||||
- [BinarySearch](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#BinarySearch)
|
||||
- [BinaryIterativeSearch](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#BinaryIterativeSearch)
|
||||
- [LinearSearch](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#LinearSearch)
|
||||
- [LRUCache](https://github.com/duke-git/lancet/blob/main/docs/algorithm_zh-CN.md#LRUCache)
|
||||
|
||||
- 函数列表:
|
||||
### convertor转换器包支持一些常见的数据类型转换。
|
||||
|
||||
```go
|
||||
func ColorHexToRGB(colorHex string) (red, green, blue int) //颜色值16进制转rgb
|
||||
func ColorRGBToHex(red, green, blue int) string //颜色值rgb转16进制
|
||||
func ToBool(s string) (bool, error) //字符串转成Bool
|
||||
func ToBytes(data interface{}) ([]byte, error) //interface转成byte slice
|
||||
func ToChar(s string) []string //字符串转成字符slice
|
||||
func ToFloat(value interface{}) (float64, error) //interface转成float64
|
||||
func ToInt(value interface{}) (int64, error) //interface转成int64
|
||||
func ToJson(value interface{}) (string, error) //interface转成json string
|
||||
func ToString(value interface{}) string //interface转成string
|
||||
func StructToMap(value interface{}) (map[string]interface{}, error) //struct串转成map, 需要设置struct tag `json`
|
||||
import "github.com/duke-git/lancet/v2/convertor"
|
||||
```
|
||||
|
||||
### 2. cryptor加解密包
|
||||
|
||||
- 加密函数支持md5, hmac, aes, des, ras
|
||||
- 导入包:import "github.com/duke-git/lancet/cryptor"
|
||||
#### 函数列表:
|
||||
- [ColorHexToRGB](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ColorHexToRGB)
|
||||
- [ColorRGBToHex](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ColorRGBToHex)
|
||||
- [ToBool](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToBool)
|
||||
- [ToBytes](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToBytes)
|
||||
- [ToChar](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToChar)
|
||||
- [ToInt](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToInt)
|
||||
- [ToJson](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToJson)
|
||||
- [ToString](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToString)
|
||||
- [StructToMap](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#StructToMap)
|
||||
|
||||
### cryptor加密包支持数据加密和解密,获取md5,hash值。支持base64, md5, hmac, aes, des, rsa。
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/cryptor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := "hello"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
|
||||
decrypted := cryptor.AesCbcDecrypt(encrypted, []byte(key))
|
||||
fmt.Println(string(decrypted)) // hello
|
||||
}
|
||||
import "github.com/duke-git/lancet/v2/cryptor"
|
||||
```
|
||||
|
||||
- 函数列表:
|
||||
#### 函数列表:
|
||||
- [AesEcbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesEcbEncrypt)
|
||||
- [AesEcbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesEcbDecrypt)
|
||||
- [AesCbcEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCbcEncrypt)
|
||||
- [AesCbcDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCbcDecrypt)
|
||||
- [AesCtrCrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCtrCrypt)
|
||||
- [AesCfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCfbEncrypt)
|
||||
- [AesCfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCfbDecrypt)
|
||||
- [AesOfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesOfbEncrypt)
|
||||
- [AesOfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesOfbDecrypt)
|
||||
- [Base64StdEncode](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Base64StdEncode)
|
||||
- [Base64StdDecode](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Base64StdDecode)
|
||||
- [DesEcbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesEcbEncrypt)
|
||||
- [DesEcbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesEcbDecrypt)
|
||||
- [DesCbcEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCbcEncrypt)
|
||||
- [DesCbcDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCbcDecrypt)
|
||||
- [DesCtrCrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCtrCrypt)
|
||||
- [DesCfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCfbEncrypt)
|
||||
- [DesCfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCfbDecrypt)
|
||||
- [DesOfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesOfbEncrypt)
|
||||
- [DesOfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesOfbDecrypt)
|
||||
- [HmacMd5](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#HmacMd5)
|
||||
- [HmacSha1](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#HmacSha1)
|
||||
- [HmacSha256](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#HmacSha256)
|
||||
- [HmacSha512](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#HmacSha512)
|
||||
- [Md5String](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Md5String)
|
||||
- [Md5File](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Md5File)
|
||||
- [Sha1](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Sha1)
|
||||
- [Sha256](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Sha256)
|
||||
- [Sha512](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Sha512)
|
||||
- [GenerateRsaKey](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#GenerateRsaKey)
|
||||
- [RsaEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#RsaEncrypt)
|
||||
- [RsaDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#RsaDecrypt)
|
||||
|
||||
### datetime日期时间处理包,格式化日期,比较日期。
|
||||
|
||||
|
||||
```go
|
||||
func AesEcbEncrypt(data, key []byte) []byte //AES ECB模式加密
|
||||
func AesEcbDecrypt(encrypted, key []byte) []byte //AES ECB模式解密
|
||||
func AesCbcEncrypt(data, key []byte) []byte //AES CBC模式加密
|
||||
func AesCbcDecrypt(encrypted, key []byte) []byte //AES CBC模式解密
|
||||
func AesCtrCrypt(data, key []byte) []byte //AES CTR模式加密/解密
|
||||
func AesCfbEncrypt(data, key []byte) []byte //AES CFB模式加密
|
||||
func AesCfbDecrypt(encrypted, key []byte) []byte //AES CFB模式解密
|
||||
func AesOfbEncrypt(data, key []byte) []byte //AES OFB模式加密
|
||||
func AesOfbDecrypt(data, key []byte) []byte //AES OFB模式解密
|
||||
func Base64StdEncode(s string) string //base64编码
|
||||
func Base64StdDecode(s string) string //base64解码
|
||||
func DesCbcEncrypt(data, key []byte) []byte //DES CBC模式加密
|
||||
func DesCbcDecrypt(encrypted, key []byte) []byte //DES CBC模式解密
|
||||
func DesCtrCrypt(data, key []byte) []byte //DES CTR模式加密/解密
|
||||
func DesCfbEncrypt(data, key []byte) []byte //DES CFB模式加密
|
||||
func DesCfbDecrypt(encrypted, key []byte) []byte //DES CFB模式解密
|
||||
func DesOfbEncrypt(data, key []byte) []byte //DES OFB模式加密
|
||||
func DesOfbDecrypt(data, key []byte) []byte //DES OFB模式解密
|
||||
func HmacMd5(data, key string) string //获取hmac md5值
|
||||
func HmacSha1(data, key string) string //获取hmac sha1值
|
||||
func HmacSha256(data, key string) string //获取hmac sha256值
|
||||
func HmacSha512(data, key string) string //获取hmac sha512值
|
||||
func Md5String(s string) string //获取字符串md5值
|
||||
func Md5File(filename string) (string, error) //获取文件md5值
|
||||
func Sha1(data string) string //获取sha1值
|
||||
func Sha256(data string) string //获取sha256值
|
||||
func Sha512(data string) string //获取sha512值
|
||||
func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) //生成RSA私钥文件
|
||||
func RsaEncrypt(data []byte, pubKeyFileName string) []byte //RSA加密
|
||||
func RsaDecrypt(data []byte, privateKeyFileName string) []byte //RSA解密
|
||||
|
||||
import "github.com/duke-git/lancet/v2/datetime"
|
||||
```
|
||||
#### 函数列表:
|
||||
- [AddDay](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#AddDay)
|
||||
- [AddHour](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#AddHour)
|
||||
- [AddMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#AddMinute)
|
||||
- [BeginOfMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfMinute)
|
||||
- [BeginOfHour](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfHour)
|
||||
- [BeginOfDay](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfDay)
|
||||
- [BeginOfWeek](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfWeek)
|
||||
- [BeginOfMonth](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfMonth)
|
||||
- [BeginOfYear](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfYear)
|
||||
- [EndOfMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfMinute)
|
||||
- [EndOfHour](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfHour)
|
||||
- [EndOfDay](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfDay)
|
||||
- [EndOfWeek](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfWeek)
|
||||
- [EndOfMonth](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfMonth)
|
||||
- [EndOfYear](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfYear)
|
||||
- [GetNowDate](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetNowDate)
|
||||
- [GetNowTime](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetNowTime)
|
||||
- [GetNowDateTime](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetNowDateTime)
|
||||
- [GetZeroHourTimestamp](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetZeroHourTimestamp)
|
||||
- [GetNightTimestamp](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetNightTimestamp)
|
||||
- [FormatTimeToStr](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#FormatTimeToStr)
|
||||
- [FormatStrToTime](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#FormatStrToTime)
|
||||
- [NewUnix](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#NewUnix)
|
||||
- [NewUnixNow](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#NewUnixNow)
|
||||
- [NewFormat](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#NewFormat)
|
||||
- [NewISO8601](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#NewISO8601)
|
||||
- [ToUnix](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToUnix)
|
||||
- [ToFormat](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToFormat)
|
||||
- [ToFormatForTpl](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToFormatForTpl)
|
||||
- [ToIso8601](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToIso8601)
|
||||
|
||||
### 3. datetime日期时间处理包
|
||||
|
||||
- 处理日期时间
|
||||
- 导入包:import "github.com/duke-git/lancet/datetime"
|
||||
### fileutil包支持文件基本操作。
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
s := datetime.FormatTimeToStr(now, "yyyy-mm-dd hh:mm:ss")
|
||||
fmt.Println(s) // 2021-11-24 11:16:55
|
||||
}
|
||||
import "github.com/duke-git/lancet/v2/fileutil"
|
||||
```
|
||||
|
||||
- 函数列表:
|
||||
#### 函数列表:
|
||||
|
||||
- [ClearFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#ClearFile)
|
||||
- [CreateFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#CreateFile)
|
||||
- [CopyFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#CopyFile)
|
||||
- [FileMode](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#FileMode)
|
||||
- [MiMeType](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#MiMeType)
|
||||
- [IsExist](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#IsExist)
|
||||
- [IsLink](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#IsLink)
|
||||
- [IsDir](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#IsDir)
|
||||
- [ListFileNames](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#ListFileNames)
|
||||
- [RemoveFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#RemoveFile)
|
||||
- [ReadFileToString](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#ReadFileToString)
|
||||
- [ReadFileByLine](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#ReadFileByLine)
|
||||
- [Zip](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#Zip)
|
||||
- [UnZip](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#UnZip)
|
||||
|
||||
### formatter格式化器包含一些数据格式化处理方法。
|
||||
|
||||
```go
|
||||
func AddDay(t time.Time, day int64) time.Time //加减天数
|
||||
func AddHour(t time.Time, hour int64) time.Time //加减小时数
|
||||
func AddMinute(t time.Time, minute int64) time.Time //加减分钟数
|
||||
func GetNowDate() string //获取当天日期 格式yyyy-mm-dd
|
||||
func GetNowTime() string //获取当前时间 格式hh:mm:ss
|
||||
func GetNowDateTime() string //获取当前日期时间 格式yyyy-mm-dd hh:mm:ss
|
||||
func GetZeroHourTimestamp() int64 //获取当天零时时间戳(00:00)
|
||||
func GetNightTimestamp() int64 //获取当天23时时间戳(23:59)
|
||||
func FormatTimeToStr(t time.Time, format string) string //时间格式化字符串
|
||||
func FormatStrToTime(str, format string) time.Time //字符串转换成时间
|
||||
import "github.com/duke-git/lancet/v2/formatter"
|
||||
```
|
||||
#### 函数列表:
|
||||
- [Comma](https://github.com/duke-git/lancet/blob/main/docs/formatter_zh-CN.md#Comma)
|
||||
|
||||
### 4. fileutil文件处理包
|
||||
|
||||
- 文件处理常用函数
|
||||
- 导入包:import "github.com/duke-git/lancet/fileutil"
|
||||
### function函数包控制函数执行流程,包含部分函数式编程。
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(fileutil.IsDir("./")) // true
|
||||
}
|
||||
import "github.com/duke-git/lancet/v2/function"
|
||||
```
|
||||
|
||||
- 函数列表:
|
||||
#### 函数列表:
|
||||
- [After](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#After)
|
||||
- [Before](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Before)
|
||||
- [Curry](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Curry)
|
||||
- [Compose](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Compose)
|
||||
- [Debounced](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Debounced)
|
||||
- [Delay](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Delay)
|
||||
- [Watcher](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Watcher)
|
||||
|
||||
### mathutil包实现了一些数学计算的函数。
|
||||
|
||||
```go
|
||||
func ClearFile(path string) error //清空文件内容
|
||||
func CreateFile(path string) bool //创建文件
|
||||
func FileMode(path string) (fs.FileMode, error) //返回文件mode信息
|
||||
func MiMeType(file interface{}) string //返回文件mime类型
|
||||
func IsExist(path string) bool //判断文件/目录是否存在
|
||||
func IsDir(path string) bool //判断是否为目录
|
||||
func IsLink(path string) bool //检查文件是否为符号链接文件
|
||||
func RemoveFile(path string) error //删除文件
|
||||
func CopyFile(srcFilePath string, dstFilePath string) error //复制文件
|
||||
func ListFileNames(path string) ([]string, error) //列出目录下所有文件名称
|
||||
func ReadFileToString(path string) (string, error) //读取文件内容为字符串
|
||||
func ReadFileByLine(path string)([]string, error) //按行读取文件内容
|
||||
func Zip(fpath string, destPath string) error //压缩文件fpath参数可以是文件或目录,destPath是压缩后目标文件
|
||||
func UnZip(zipFile string, destPath string) error //解压文件,并将文件存储在destPath目录中
|
||||
import "github.com/duke-git/lancet/v2/mathutil"
|
||||
```
|
||||
|
||||
### 5. formatter格式化处理包
|
||||
#### Function list:
|
||||
- [Average](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Average)
|
||||
- [Exponent](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Exponent)
|
||||
- [Fibonacci](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Fibonacci)
|
||||
- [Factorial](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Factorial)
|
||||
- [Max](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Max)
|
||||
- [Min](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Min)
|
||||
- [Percent](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Percent)
|
||||
- [RoundToFloat](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#RoundToFloat)
|
||||
- [RoundToString](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#RoundToString)
|
||||
- [TruncRound](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#TruncRound)
|
||||
|
||||
- 格式化相关处理函数
|
||||
- 导入包:import "github.com/duke-git/lancet/formatter"
|
||||
### netutil网络包支持获取ip地址,发送http请求。
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/formatter"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(formatter.Comma("12345", "")) // "12,345"
|
||||
fmt.Println(formatter.Comma(12345.67, "¥")) // "¥12,345.67"
|
||||
}
|
||||
import "github.com/duke-git/lancet/v2/netutil"
|
||||
```
|
||||
|
||||
- 函数列表:
|
||||
#### 函数列表:
|
||||
- [ConvertMapToQueryString](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#ConvertMapToQueryString)
|
||||
- [GetInternalIp](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#GetInternalIp)
|
||||
- [GetIps](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetIps)
|
||||
- [GetMacAddrs](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetMacAddrs)
|
||||
- [GetPublicIpInfo](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#GetPublicIpInfo)
|
||||
- [IsPublicIP](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#IsPublicIP)
|
||||
- [HttpGet](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpGet)
|
||||
- [HttpDelete](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpDelete)
|
||||
- [HttpPost](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPost)
|
||||
- [HttpPut](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPut)
|
||||
- [HttpPatch](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPatch)
|
||||
- [ParseHttpResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#ParseHttpResponse)
|
||||
|
||||
### random随机数生成器包,可以生成随机[]bytes, int, string。
|
||||
|
||||
```go
|
||||
func Comma(v interface{}, symbol string) string //用逗号每隔3位分割数字/字符串
|
||||
import "github.com/duke-git/lancet/v2/random"
|
||||
```
|
||||
|
||||
### 6. function包可以控制函数执行,支持部分函数式编程
|
||||
|
||||
- 控制函数执行,支持部分函数式编程
|
||||
- 导入包:import "github.com/duke-git/lancet/function"
|
||||
#### 函数列表:
|
||||
- [RandBytes](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandBytes)
|
||||
- [RandInt](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandInt)
|
||||
- [RandString](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandString)
|
||||
- [UUIdV4](https://github.com/duke-git/lancet/blob/main/docs/random.md#UUIdV4)
|
||||
### retry重试执行函数直到函数运行成功或被context cancel。
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/function"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var print = func(s string) {
|
||||
fmt.Println(s)
|
||||
}
|
||||
function.Delay(2*time.Second, print, "hello world")
|
||||
}
|
||||
import "github.com/duke-git/lancet/v2/retry"
|
||||
```
|
||||
|
||||
- Function list:
|
||||
#### 函数列表:
|
||||
- [Context](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#Context)
|
||||
- [Retry](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#Retry)
|
||||
- [RetryFunc](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryFunc)
|
||||
- [RetryDuration](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryDuration)
|
||||
- [RetryTimes](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryTimes)
|
||||
|
||||
|
||||
### slice包包含操作切片的方法集合。
|
||||
|
||||
```go
|
||||
func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value //创建一个函数, 只有在运行了n次之后才有效果
|
||||
func Before(n int, fn interface{}) func(args ...interface{}) []reflect.Value //创建一个函数,调用不超过n次。 当n已经达到时,最后一个函数调用的结果将被记住并返回
|
||||
func (f Fn) Curry(i interface{}) func(...interface{}) interface{} //函数柯里化
|
||||
func Compose(fnList ...func(...interface{}) interface{}) func(...interface{}) interface{} //从右至左组合函数
|
||||
func Delay(delay time.Duration, fn interface{}, args ...interface{}) //延迟调用函数
|
||||
func Debounced(fn func(), duration time.Duration) func() //go防抖函数,在duration时间内连续调用只会执行一次.
|
||||
func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool //每隔duration时间调用函数, 关闭返回通道可以停止调用
|
||||
func (w *Watcher) Start() //开时watcher
|
||||
func (w *Watcher) Stop() //开时watcher
|
||||
func (w *Watcher) Reset() {} //重置代码watcher
|
||||
func (w *Watcher) GetElapsedTime() time.Duration //get code excution elapsed time.
|
||||
import "github.com/duke-git/lancet/v2/slice"
|
||||
```
|
||||
|
||||
### 7. netutil网络处理包
|
||||
#### 函数列表:
|
||||
- [Contain](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Contain)
|
||||
- [ContainSubSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ContainSubSlice)
|
||||
- [Chunk](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Chunk)
|
||||
- [Compact](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Compact)
|
||||
- [Concat](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Concat)
|
||||
- [Count](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Count)
|
||||
- [Difference](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Difference)
|
||||
- [DifferenceBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#DifferenceBy)
|
||||
- [DifferenceWith](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DifferenceWith)
|
||||
- [DeleteAt](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#DeleteAt)
|
||||
- [Drop](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Drop)
|
||||
- [Every](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Every)
|
||||
- [Filter](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Filter)
|
||||
- [Find](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Find)
|
||||
- [FindLast](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#FindLast)
|
||||
- [FlattenDeep](#FlattenDeep)
|
||||
- [ForEach](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ForEach)
|
||||
- [GroupBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#GroupBy)
|
||||
- [GroupWith](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#GroupWith)
|
||||
- [IntSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#IntSlice)
|
||||
- [InterfaceSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#InterfaceSlice)
|
||||
- [Intersection](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Intersection)
|
||||
- [InsertAt](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#InsertAt)
|
||||
- [Map](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Map)
|
||||
- [Reverse](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Reverse)
|
||||
- [Reduce](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Reduce)
|
||||
- [Shuffle](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Shuffle)
|
||||
- [SortByField](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#SortByField)
|
||||
- [Some](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Some)
|
||||
- [StringSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#StringSlice)
|
||||
- [Unique](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Unique)
|
||||
- [Union](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Union)
|
||||
- [UpdateAt](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#UpdateAt)
|
||||
- [Without](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Without)
|
||||
|
||||
- 处理ip, http请求相关函数
|
||||
- 导入包:import "github.com/duke-git/lancet/netutil"
|
||||
- http方法params参数顺序:header, query string, body, httpclient
|
||||
|
||||
### strutil包含处理字符串的相关函数。
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
url := "https://gutendex.com/books?"
|
||||
header := make(map[string]string)
|
||||
header["Content-Type"] = "application/json"
|
||||
queryParams := make(map[string]interface{})
|
||||
queryParams["ids"] = "1"
|
||||
|
||||
resp, err := netutil.HttpGet(url, header, queryParams)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
fmt.Println("response: ", resp.StatusCode, string(body))
|
||||
}
|
||||
import "github.com/duke-git/lancet/v2/strutil"
|
||||
```
|
||||
|
||||
- 函数列表:
|
||||
#### 函数列表:
|
||||
|
||||
- [After](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#After)
|
||||
- [AfterLast](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#AfterLast)
|
||||
- [Before](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Before)
|
||||
- [BeforeLast](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#BeforeLast)
|
||||
- [CamelCase](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#CamelCase)
|
||||
- [Capitalize](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Capitalize)
|
||||
- [IsString](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#IsString)
|
||||
- [KebabCase](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#KebabCase)
|
||||
- [LowerFirst](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#LowerFirst)
|
||||
- [UpperFirst](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#UpperFirst)
|
||||
- [PadEnd](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#PadEnd)
|
||||
- [PadStart](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#PadStart)
|
||||
- [ReverseStr](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#ReverseStr)
|
||||
- [SnakeCase](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#SnakeCase)
|
||||
- [Wrap](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Wrap)
|
||||
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Unwrap)
|
||||
|
||||
|
||||
### system包含os, runtime, shell command相关函数。
|
||||
|
||||
```go
|
||||
func GetInternalIp() string //获取内部ip
|
||||
func GetPublicIpInfo() (*PublicIpInfo, error) //获取公共ip信息: country, region, isp, city, lat, lon, ip
|
||||
func IsPublicIP(IP net.IP) bool //判断ip是否为公共ip
|
||||
func HttpGet(url string, params ...interface{}) (*http.Response, error) //http get请求
|
||||
func HttpPost(url string, params ...interface{}) (*http.Response, error) //http post请求
|
||||
func HttpPut(url string, params ...interface{}) (*http.Response, error) //http put请求
|
||||
func HttpDelete(url string, params ...interface{}) (*http.Response, error) //http delete请求
|
||||
func HttpPatch(url string, params ...interface{}) (*http.Response, error) //http patch请求
|
||||
func ConvertMapToQueryString(param map[string]interface{}) string //将map转换成url query string
|
||||
func ParseHttpResponse(resp *http.Response, obj interface{}) error //将http响应解码成特定interface
|
||||
import "github.com/duke-git/lancet/v2/system"
|
||||
```
|
||||
|
||||
### 8. random随机数处理包
|
||||
#### 函数列表:
|
||||
- [IsWindows](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#IsWindows)
|
||||
- [IsLinux](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#IsLinux)
|
||||
- [IsMac](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#IsMac)
|
||||
- [GetOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#GetOsEnv)
|
||||
- [SetOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#SetOsEnv)
|
||||
- [RemoveOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#RemoveOsEnv)
|
||||
- [CompareOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#CompareOsEnv)
|
||||
- [ExecCommand](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#ExecCommand)
|
||||
|
||||
- 生成和处理随机数
|
||||
- 导入包:import "github.com/duke-git/lancet/random"
|
||||
### validator验证器包,包含常用字符串格式验证函数。
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/random"
|
||||
)
|
||||
|
||||
func main() {
|
||||
randStr := random.RandString(6)
|
||||
fmt.Println(randStr)
|
||||
}
|
||||
import "github.com/duke-git/lancet/v2/validator"
|
||||
```
|
||||
#### 函数列表:
|
||||
|
||||
- 函数列表:
|
||||
- [ContainChinese](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#ContainChinese)
|
||||
- [ContainLetter](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#ContainLetter)
|
||||
- [ContainLower](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#ContainLower)
|
||||
- [ContainUpper](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#ContainUpper)
|
||||
- [IsAlpha](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsAlpha)
|
||||
- [IsAllUpper](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsAllUpper)
|
||||
- [IsAllLower](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsAllLower)
|
||||
- [IsBase64](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsBase64)
|
||||
- [IsChineseMobile](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsChineseMobile)
|
||||
- [IsChineseIdNum](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsChineseIdNum)
|
||||
- [IsChinesePhone](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsChinesePhone)
|
||||
- [IsCreditCard](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsCreditCard)
|
||||
- [IsDns](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsDns)
|
||||
- [IsEmail](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsEmail)
|
||||
- [IsEmptyString](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsEmptyString)
|
||||
- [IsFloatStr](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsFloatStr)
|
||||
- [IsNumberStr](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsNumberStr)
|
||||
- [IsJSON](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsJSON)
|
||||
- [IsRegexMatch](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsRegexMatch)
|
||||
- [IsIntStr](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsIntStr)
|
||||
- [IsIp](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsIp)
|
||||
- [IsIpV4](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsIpV4)
|
||||
- [IsIpV6](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsIpV6)
|
||||
- [IsStrongPassword](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsStrongPassword)
|
||||
- [IsUrl](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsUrl)
|
||||
- [IsWeakPassword](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsWeakPassword)
|
||||
|
||||
validator.md#IsWeakPassword)
|
||||
### xerror包实现一些错误处理函数
|
||||
|
||||
```go
|
||||
func RandBytes(length int) []byte //生成随机[]byte
|
||||
func RandInt(min, max int) int //生成随机int
|
||||
func RandString(length int) string //生成随机string
|
||||
import "github.com/duke-git/lancet/v2/xerror"
|
||||
```
|
||||
#### 函数列表:
|
||||
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#Unwrap)
|
||||
|
||||
### 9. retry重试执行函数
|
||||
## 如何贡献代码
|
||||
|
||||
- 重试执行函数直到函数成功或被context停止
|
||||
- 默认重试次数5, 默认执行间隔3秒.
|
||||
- Usage: import "github.com/duke-git/lancet/retry".
|
||||
非常感激任何的代码提交以使lancet的功能越来越强大。创建pull request时请遵守以下规则。
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/retry"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var number int
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
||||
|
||||
fmt.Println(number) //3
|
||||
}
|
||||
```
|
||||
|
||||
- Function list:
|
||||
|
||||
```go
|
||||
type RetryFunc func() error //要重试执行的函数
|
||||
func RetryTimes(n uint) //设置重试次数,默认5次
|
||||
func RetryDuration(d time.Duration) //设置重试间隔时间,默认3秒
|
||||
func Context(ctx context.Context) //context config
|
||||
func Retry(retryFunc RetryFunc, opts ...Option) error //重试函数
|
||||
```
|
||||
|
||||
### 10. slice切片操作包
|
||||
|
||||
- 切片操作相关函数
|
||||
- 导入包:import "github.com/duke-git/lancet/slice"
|
||||
- 由于go目前对范型支持不稳定,slice处理函数参数和返回值大部分为interface{}, 待范型特性稳定后,会重构相关函数
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/slice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
nums := []int{1, 4, 3, 4, 6, 7, 3}
|
||||
uniqueNums, _ := slice.IntSlice(slice.Unique(nums))
|
||||
fmt.Println(uniqueNums) //[1 4 3 6 7]
|
||||
}
|
||||
```
|
||||
|
||||
- 函数列表:
|
||||
|
||||
```go
|
||||
func Contain(slice interface{}, value interface{}) bool //判断slice是否包含value
|
||||
func ContainSubSlice(slice interface{}, subslice interface{}) bool //判断slice是否包含subslice
|
||||
func Chunk(slice []interface{}, size int) [][]interface{} //均分slice
|
||||
func Compact(slice interface{}) interface{} //去除slice中的false vule. false values are false, nil, 0, and ""
|
||||
func Concat(slice interface{}, values ...interface{}) interface{} //连接values到slice中
|
||||
func Difference(slice1, slice2 interface{}) interface{} //返回切片,其元素在slice1中,不在slice2中
|
||||
func DifferenceBy(slice interface{}, comparedSlice interface{}, iterateeFn interface{}) interface{} //将slice 和comparedSlice中每个元素调用iterateeFn后作比较,如果不相等返回slice中的元素。
|
||||
func DeleteByIndex(slice interface{}, start int, end ...int) (interface{}, error) //删除切片中start到end位置的值
|
||||
func Drop(slice interface{}, n int) interface{} //创建一个新切片,当n大于0时删除原切片前n个元素,当n小于0时删除原切片后n个元素
|
||||
func Every(slice, function interface{}) bool //slice中所有元素都符合函数条件时返回true, 否则返回false. 函数签名:func(index int, value interface{}) bool
|
||||
func None(slice, function interface{}) bool //slice中所有元素都不符合函数条件时返回true, 否则返回false. 函数签名:func(index int, value interface{}) bool
|
||||
func Find(slice, function interface{}) (interface{}, bool)//查找slice中第一个符合条件的元素,函数签名:func(index int, value interface{}) bool
|
||||
func Filter(slice, function interface{}) interface{} //过滤slice, 函数签名:func(index int, value interface{}) bool
|
||||
func FlattenDeep(slice interface{}) interface{} //将slice递归为一维切片。
|
||||
func ForEach(slice, function interface{}) //遍历切片,在每个元素上执行函数,函数签名:func(index int, value interface{})
|
||||
func IntSlice(slice interface{}) ([]int, error) //转成int切片
|
||||
func InterfaceSlice(slice interface{}) []interface{} //转成interface{}切片
|
||||
func Intersection(slices ...interface{}) interface{} //slice交集,去重
|
||||
func InsertByIndex(slice interface{}, index int, value interface{}) (interface{}, error) //在切片中index位置插入value
|
||||
func Map(slice, function interface{}) interface{} //遍历切片, 函数签名:func(index int, value interface{}) interface{}
|
||||
func ReverseSlice(slice interface{}) //反转切片
|
||||
func Reduce(slice, function, zero interface{}) interface{} //切片reduce操作, 函数签名:func(index int, value1, value2 interface{}) interface{}
|
||||
func Shuffle(slice interface{}) interface{} //创建一个被打乱值的切片
|
||||
func Some(slice, function interface{}) bool //slice中任意一个元素都符合函数条件时返回true, 否则返回false. 函数签名:func(index int, value interface{}) bool
|
||||
func SortByField(slice interface{}, field string, sortType ...string) error //对struct切片进行排序
|
||||
func StringSlice(slice interface{}) []string //转为string切片
|
||||
func Unique(slice interface{}) interface{} //去重切片
|
||||
func Union(slices ...interface{}) interface{} //slice并集, 去重
|
||||
func UpdateByIndex(slice interface{}, index int, value interface{}) (interface{}, error) //在切片中index位置更新value
|
||||
func Without(slice interface{}, values ...interface{}) interface{} //slice去除values
|
||||
func GroupBy(slice, function interface{}) (interface{}, interface{}) //根据函数function的逻辑分slice为两组slice
|
||||
func Count(slice, function interface{}) int
|
||||
```
|
||||
|
||||
### 11. strutil字符串处理包
|
||||
|
||||
- 字符串操作相关函数
|
||||
- 导入包:import "github.com/duke-git/lancet/strutil"
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
str := "Foo-Bar"
|
||||
camelCaseStr := strutil.CamelCase(str)
|
||||
fmt.Println(camelCaseStr) //fooBar
|
||||
}
|
||||
```
|
||||
|
||||
- 函数列表:
|
||||
|
||||
```go
|
||||
func After(s, char string) string //截取字符串中char第一次出现之后的字符串
|
||||
func AfterLast(s, char string) string //截取字符串中char最后一次出现之后的字符串
|
||||
func Before(s, char string) string //截取字符串中char第一次出现之前的字符串
|
||||
func BeforeLast(s, char string) string //截取字符串中char最后一次出现之前的字符串
|
||||
func CamelCase(s string) string //字符串转为cameCase, "foo bar" -> "fooBar"
|
||||
func Capitalize(s string) string //字符串转为Capitalize, "fOO" -> "Foo"
|
||||
func IsString(v interface{}) bool //判断是否是字符串
|
||||
func KebabCase(s string) string //字符串转为KebabCase, "foo_Bar" -> "foo-bar"
|
||||
func UpperFirst(s string) string //字符串的第一个字母转为大写字母
|
||||
func LowerFirst(s string) string //字符串的第一个字母转为小写字母
|
||||
func PadEnd(source string, size int, padStr string) string //字符串末尾填充size个字符
|
||||
func PadStart(source string, size int, padStr string) string//字符串开头填充size个字符
|
||||
func ReverseStr(s string) string //字符串逆序
|
||||
func Wrap(str string, wrapWith string) string //包裹字符串 Wrap("abc", "*") -> *abc*.
|
||||
func Unwrap(str string, wrapToken string) string //解包裹字符串 Wrap("*abc*", "*") -> abc.
|
||||
func SnakeCase(s string) string //字符串转为SnakeCase, "fooBar" -> "foo_bar"
|
||||
```
|
||||
|
||||
### 12. system系统包
|
||||
|
||||
- 包含一些操作系统,运行时,shell命令执行的函数.
|
||||
- Usage: import "github.com/duke-git/lancet/system".
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
envFoo := system.GetOsEnv("foo")
|
||||
fmt.Println(envFoo)
|
||||
}
|
||||
```
|
||||
|
||||
- Function list:
|
||||
|
||||
```go
|
||||
func IsWindows() bool //判断操作系统是windows
|
||||
func IsLinux() bool //判断操作系统是linux
|
||||
func IsMac() bool //判断操作系统是macos
|
||||
func GetOsEnv(key string) string //获取名称为key的环境变量
|
||||
func SetOsEnv(key, value string) error //设置环境变量
|
||||
func RemoveOsEnv(key string) error //删除指定key的环境变量
|
||||
func CompareOsEnv(key, comparedEnv string) bool //获取名称为key的环境变量并和comparedEnv比较
|
||||
func ExecCommand(command string) (stdout, stderr string, err error) //执行shell命令(/bin/bash)
|
||||
```
|
||||
|
||||
### 13. validator验证器包
|
||||
|
||||
- 数据校验相关函数
|
||||
- 导入包:import "github.com/duke-git/lancet/validator"
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
str := "Foo-Bar"
|
||||
isAlpha := validator.IsAlpha(str)
|
||||
fmt.Println(isAlpha) //false
|
||||
}
|
||||
```
|
||||
|
||||
- 函数列表:
|
||||
|
||||
```go
|
||||
func ContainChinese(s string) bool //判断字符串中是否含有中文字符
|
||||
func IsAlpha(s string) bool //判断字符串是否只含有字母
|
||||
func IsBase64(base64 string) bool //判断字符串是base64
|
||||
func IsAllUpper(str string) bool //断字符串是否全是大写字母
|
||||
func IsAllLower(str string) bool //断字符串是否全是小写字母
|
||||
func ContainUpper(str string) bool //判断字符串是否包含大写字母
|
||||
func ContainLower(str string) bool //判断字符串是否包含小写字母
|
||||
func ContainLetter(str string) bool //判断字符串是否包含字母
|
||||
func IsJSON(str string) bool //判断字符串是否是JSON
|
||||
func IsChineseMobile(mobileNum string) bool //判断字符串是否是手机号
|
||||
func IsChineseIdNum(id string) bool //判断字符串是否是身份证号
|
||||
func IsChinesePhone(phone string) bool //判断字符串是否是座机电话号码
|
||||
func IsCreditCard(creditCart string) bool //判断字符串是否是信用卡
|
||||
func IsDns(dns string) bool //判断字符串是否是DNS
|
||||
func IsEmail(email string) bool //判断字符串是否是邮箱
|
||||
func IsEmptyString(s string) bool //判断字符串是否为空
|
||||
func IsFloatStr(s string) bool //判断字符串是否可以转成float
|
||||
func IsNumberStr(s string) bool //判断字符串是否可以转成数字
|
||||
func IsRegexMatch(s, regex string) bool //判断字符串是否match正则表达式
|
||||
func IsIntStr(s string) bool //判断字符串是否可以转成整数
|
||||
func IsIp(ipstr string) bool //判断字符串是否是ip
|
||||
func IsIpV4(ipstr string) bool //判断字符串是否是ipv4
|
||||
func IsIpV6(ipstr string) bool //判断字符串是否是ipv6
|
||||
func IsStrongPassword(password string, length int) bool //判断字符串是否是强密码(大小写字母+数字+特殊字符)
|
||||
func IsUrl(str string) bool //判断字符串是否是url
|
||||
func IsWeakPassword(password string) bool //判断字符串是否是弱密码(只有字母或数字)
|
||||
```
|
||||
1. Fork lancet仓库。
|
||||
2. 创建自己的特性分支。
|
||||
3. 提交变更。
|
||||
4. Push分支。
|
||||
5. 创建新的pull request。
|
||||
|
||||
102
algorithm/lru_cache.go
Normal file
102
algorithm/lru_cache.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package algorithm
|
||||
|
||||
type lruNode[K comparable, V any] struct {
|
||||
key K
|
||||
value V
|
||||
pre *lruNode[K, V]
|
||||
next *lruNode[K, V]
|
||||
}
|
||||
|
||||
// newLruNode return a lruNode pointer
|
||||
func newLruNode[K comparable, V any](key K, value V) *lruNode[K, V] {
|
||||
return &lruNode[K, V]{
|
||||
key: key,
|
||||
value: value,
|
||||
pre: nil,
|
||||
next: nil,
|
||||
}
|
||||
}
|
||||
|
||||
// LRUCache lru cache (thread unsafe)
|
||||
type LRUCache[K comparable, V any] struct {
|
||||
cache map[K]*lruNode[K, V]
|
||||
head *lruNode[K, V]
|
||||
tail *lruNode[K, V]
|
||||
capacity int
|
||||
length int
|
||||
}
|
||||
|
||||
// NewLRUCache return a LRUCache pointer
|
||||
func NewLRUCache[K comparable, V any](capacity int) *LRUCache[K, V] {
|
||||
return &LRUCache[K, V]{
|
||||
cache: make(map[K]*lruNode[K, V], capacity),
|
||||
head: nil,
|
||||
tail: nil,
|
||||
capacity: capacity,
|
||||
length: 0,
|
||||
}
|
||||
}
|
||||
|
||||
// Get value of key from lru cache
|
||||
func (l *LRUCache[K, V]) Get(key K) (V, bool) {
|
||||
var value V
|
||||
|
||||
node, ok := l.cache[key]
|
||||
if ok {
|
||||
l.moveToHead(node)
|
||||
return node.value, true
|
||||
}
|
||||
|
||||
return value, false
|
||||
}
|
||||
|
||||
// Put value of key into lru cache
|
||||
func (l *LRUCache[K, V]) Put(key K, value V) {
|
||||
node, ok := l.cache[key]
|
||||
if !ok {
|
||||
newNode := newLruNode(key, value)
|
||||
l.cache[key] = newNode
|
||||
l.addNode(newNode)
|
||||
|
||||
if len(l.cache) > l.capacity {
|
||||
oldKey := l.deleteNode(l.head)
|
||||
delete(l.cache, oldKey)
|
||||
}
|
||||
} else {
|
||||
node.value = value
|
||||
l.moveToHead(node)
|
||||
}
|
||||
l.length = len(l.cache)
|
||||
}
|
||||
|
||||
func (l *LRUCache[K, V]) addNode(node *lruNode[K, V]) {
|
||||
if l.tail != nil {
|
||||
l.tail.next = node
|
||||
node.pre = l.tail
|
||||
node.next = nil
|
||||
}
|
||||
l.tail = node
|
||||
if l.head == nil {
|
||||
l.head = node
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LRUCache[K, V]) deleteNode(node *lruNode[K, V]) K {
|
||||
if node == l.tail {
|
||||
l.tail = l.tail.pre
|
||||
} else if node == l.head {
|
||||
l.head = l.head.next
|
||||
} else {
|
||||
node.pre.next = node.next
|
||||
node.next.pre = node.pre
|
||||
}
|
||||
return node.key
|
||||
}
|
||||
|
||||
func (l *LRUCache[K, V]) moveToHead(node *lruNode[K, V]) {
|
||||
if l.tail == node {
|
||||
return
|
||||
}
|
||||
l.deleteNode(node)
|
||||
l.addNode(node)
|
||||
}
|
||||
36
algorithm/lru_cache_test.go
Normal file
36
algorithm/lru_cache_test.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package algorithm
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestLRUCache(t *testing.T) {
|
||||
asssert := internal.NewAssert(t, "TestLRUCache")
|
||||
|
||||
cache := NewLRUCache[int, int](2)
|
||||
|
||||
cache.Put(1, 1)
|
||||
cache.Put(2, 2)
|
||||
|
||||
_, ok := cache.Get(0)
|
||||
asssert.Equal(false, ok)
|
||||
|
||||
v, ok := cache.Get(1)
|
||||
asssert.Equal(true, ok)
|
||||
asssert.Equal(1, v)
|
||||
|
||||
v, ok = cache.Get(2)
|
||||
asssert.Equal(true, ok)
|
||||
asssert.Equal(2, v)
|
||||
|
||||
cache.Put(3, 3)
|
||||
v, ok = cache.Get(1)
|
||||
asssert.Equal(false, ok)
|
||||
asssert.NotEqual(1, v)
|
||||
|
||||
v, ok = cache.Get(3)
|
||||
asssert.Equal(true, ok)
|
||||
asssert.Equal(3, v)
|
||||
}
|
||||
63
algorithm/search.go
Normal file
63
algorithm/search.go
Normal file
@@ -0,0 +1,63 @@
|
||||
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
|
||||
// Use of this source code is governed by MIT license
|
||||
|
||||
// Package algorithm contain some basic algorithm functions. eg. sort, search, list, linklist, stack, queue, tree, graph. TODO
|
||||
package algorithm
|
||||
|
||||
import "github.com/duke-git/lancet/v2/lancetconstraints"
|
||||
|
||||
// Search algorithms see https://github.com/TheAlgorithms/Go/tree/master/search
|
||||
|
||||
// LinearSearch Simple linear search algorithm that iterates over all elements of an slice
|
||||
// If a target is found, the index of the target is returned. Else the function return -1
|
||||
func LinearSearch[T any](slice []T, target T, comparator lancetconstraints.Comparator) int {
|
||||
for i, v := range slice {
|
||||
if comparator.Compare(v, target) == 0 {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// BinarySearch search for target within a sorted slice, recursive call itself.
|
||||
// If a target is found, the index of the target is returned. Else the function return -1
|
||||
func BinarySearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int {
|
||||
if highIndex < lowIndex || len(sortedSlice) == 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
midIndex := int(lowIndex + (highIndex-lowIndex)/2)
|
||||
isMidValGreatTarget := comparator.Compare(sortedSlice[midIndex], target) == 1
|
||||
isMidValLessTarget := comparator.Compare(sortedSlice[midIndex], target) == -1
|
||||
|
||||
if isMidValGreatTarget {
|
||||
return BinarySearch(sortedSlice, target, lowIndex, midIndex-1, comparator)
|
||||
} else if isMidValLessTarget {
|
||||
return BinarySearch(sortedSlice, target, midIndex+1, highIndex, comparator)
|
||||
}
|
||||
|
||||
return midIndex
|
||||
}
|
||||
|
||||
// BinaryIterativeSearch search for target within a sorted slice.
|
||||
// If a target is found, the index of the target is returned. Else the function return -1
|
||||
func BinaryIterativeSearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int {
|
||||
startIndex := lowIndex
|
||||
endIndex := highIndex
|
||||
|
||||
var midIndex int
|
||||
for startIndex <= endIndex {
|
||||
midIndex = int(startIndex + (endIndex-startIndex)/2)
|
||||
isMidValGreatTarget := comparator.Compare(sortedSlice[midIndex], target) == 1
|
||||
isMidValLessTarget := comparator.Compare(sortedSlice[midIndex], target) == -1
|
||||
|
||||
if isMidValGreatTarget {
|
||||
endIndex = midIndex - 1
|
||||
} else if isMidValLessTarget {
|
||||
startIndex = midIndex + 1
|
||||
} else {
|
||||
return midIndex
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
33
algorithm/search_test.go
Normal file
33
algorithm/search_test.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package algorithm
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
var sortedNumbers = []int{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
|
||||
func TestLinearSearch(t *testing.T) {
|
||||
asssert := internal.NewAssert(t, "TestLinearSearch")
|
||||
|
||||
comparator := &intComparator{}
|
||||
asssert.Equal(4, LinearSearch(sortedNumbers, 5, comparator))
|
||||
asssert.Equal(-1, LinearSearch(sortedNumbers, 9, comparator))
|
||||
}
|
||||
|
||||
func TestBinarySearch(t *testing.T) {
|
||||
asssert := internal.NewAssert(t, "TestBinarySearch")
|
||||
|
||||
comparator := &intComparator{}
|
||||
asssert.Equal(4, BinarySearch(sortedNumbers, 5, 0, len(sortedNumbers)-1, comparator))
|
||||
asssert.Equal(-1, BinarySearch(sortedNumbers, 9, 0, len(sortedNumbers)-1, comparator))
|
||||
}
|
||||
|
||||
func TestBinaryIterativeSearch(t *testing.T) {
|
||||
asssert := internal.NewAssert(t, "TestBinaryIterativeSearch")
|
||||
|
||||
comparator := &intComparator{}
|
||||
asssert.Equal(4, BinaryIterativeSearch(sortedNumbers, 5, 0, len(sortedNumbers)-1, comparator))
|
||||
asssert.Equal(-1, BinaryIterativeSearch(sortedNumbers, 9, 0, len(sortedNumbers)-1, comparator))
|
||||
}
|
||||
208
algorithm/sorter.go
Normal file
208
algorithm/sorter.go
Normal file
@@ -0,0 +1,208 @@
|
||||
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
|
||||
// Use of this source code is governed by MIT license
|
||||
|
||||
// Package algorithm contain some basic algorithm functions. eg. sort, search
|
||||
package algorithm
|
||||
|
||||
import "github.com/duke-git/lancet/v2/lancetconstraints"
|
||||
|
||||
// BubbleSort use bubble to sort slice.
|
||||
func BubbleSort[T any](slice []T, comparator lancetconstraints.Comparator) []T {
|
||||
for i := 0; i < len(slice); i++ {
|
||||
for j := 0; j < len(slice)-1-i; j++ {
|
||||
isCurrGreatThanNext := comparator.Compare(slice[j], slice[j+1]) == 1
|
||||
if isCurrGreatThanNext {
|
||||
swap(slice, j, j+1)
|
||||
}
|
||||
}
|
||||
}
|
||||
return slice
|
||||
}
|
||||
|
||||
// InsertionSort use insertion to sort slice.
|
||||
func InsertionSort[T any](slice []T, comparator lancetconstraints.Comparator) []T {
|
||||
size := len(slice)
|
||||
if size <= 1 {
|
||||
return slice
|
||||
}
|
||||
|
||||
for i := 1; i < size; i++ {
|
||||
currentItem := slice[i]
|
||||
preIndex := i - 1
|
||||
preItem := slice[preIndex]
|
||||
|
||||
isPreLessThanCurrent := comparator.Compare(preItem, currentItem) == -1
|
||||
for preIndex >= 0 && isPreLessThanCurrent {
|
||||
slice[preIndex+1] = slice[preIndex]
|
||||
preIndex--
|
||||
}
|
||||
|
||||
slice[preIndex+1] = currentItem
|
||||
}
|
||||
|
||||
return slice
|
||||
}
|
||||
|
||||
// SelectionSort use selection to sort slice.
|
||||
func SelectionSort[T any](slice []T, comparator lancetconstraints.Comparator) []T {
|
||||
for i := 0; i < len(slice); i++ {
|
||||
min := i
|
||||
|
||||
for j := i + 1; j < len(slice); j++ {
|
||||
if comparator.Compare(slice[j], slice[min]) == -1 {
|
||||
min = j
|
||||
}
|
||||
}
|
||||
swap(slice, i, min)
|
||||
}
|
||||
return slice
|
||||
}
|
||||
|
||||
// ShellSort shell sort slice.
|
||||
func ShellSort[T any](slice []T, comparator lancetconstraints.Comparator) []T {
|
||||
size := len(slice)
|
||||
if size <= 1 {
|
||||
return slice
|
||||
}
|
||||
|
||||
gap := 1
|
||||
for gap < size/3 {
|
||||
gap = 3*gap + 1
|
||||
}
|
||||
|
||||
for gap >= 1 {
|
||||
for i := gap; i < size; i++ {
|
||||
for j := i; j >= gap && comparator.Compare(slice[j], slice[j-gap]) == -1; j -= gap {
|
||||
swap(slice, j, j-gap)
|
||||
}
|
||||
}
|
||||
gap /= 3
|
||||
}
|
||||
|
||||
return slice
|
||||
}
|
||||
|
||||
// QuickSort quick sorting for slice, lowIndex is 0 and highIndex is len(slice)-1
|
||||
func QuickSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) []T {
|
||||
if lowIndex < highIndex {
|
||||
p := partition(slice, lowIndex, highIndex, comparator)
|
||||
QuickSort(slice, lowIndex, p-1, comparator)
|
||||
QuickSort(slice, p+1, highIndex, comparator)
|
||||
}
|
||||
|
||||
return slice
|
||||
}
|
||||
|
||||
// partition split slice into two parts
|
||||
func partition[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int {
|
||||
p := slice[highIndex]
|
||||
i := lowIndex
|
||||
for j := lowIndex; j < highIndex; j++ {
|
||||
if comparator.Compare(slice[j], p) == -1 { //slice[j] < p
|
||||
swap(slice, i, j)
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
swap(slice, i, highIndex)
|
||||
|
||||
return i
|
||||
}
|
||||
|
||||
// HeapSort use heap to sort slice
|
||||
func HeapSort[T any](slice []T, comparator lancetconstraints.Comparator) []T {
|
||||
size := len(slice)
|
||||
|
||||
for i := size/2 - 1; i >= 0; i-- {
|
||||
sift(slice, i, size-1, comparator)
|
||||
}
|
||||
for j := size - 1; j > 0; j-- {
|
||||
swap(slice, 0, j)
|
||||
sift(slice, 0, j-1, comparator)
|
||||
}
|
||||
|
||||
return slice
|
||||
}
|
||||
|
||||
func sift[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) {
|
||||
i := lowIndex
|
||||
j := 2*i + 1
|
||||
|
||||
temp := slice[i]
|
||||
for j <= highIndex {
|
||||
if j < highIndex && comparator.Compare(slice[j], slice[j+1]) == -1 { //slice[j] < slice[j+1]
|
||||
j++
|
||||
}
|
||||
if comparator.Compare(temp, slice[j]) == -1 { //tmp < slice[j]
|
||||
slice[i] = slice[j]
|
||||
i = j
|
||||
j = 2*i + 1
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
slice[i] = temp
|
||||
}
|
||||
|
||||
// MergeSort merge sorting for slice
|
||||
func MergeSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) []T {
|
||||
if lowIndex < highIndex {
|
||||
mid := (lowIndex + highIndex) / 2
|
||||
MergeSort(slice, lowIndex, mid, comparator)
|
||||
MergeSort(slice, mid+1, highIndex, comparator)
|
||||
merge(slice, lowIndex, mid, highIndex, comparator)
|
||||
}
|
||||
|
||||
return slice
|
||||
}
|
||||
|
||||
func merge[T any](slice []T, lowIndex, midIndex, highIndex int, comparator lancetconstraints.Comparator) {
|
||||
i := lowIndex
|
||||
j := midIndex + 1
|
||||
temp := []T{}
|
||||
|
||||
for i <= midIndex && j <= highIndex {
|
||||
//slice[i] < slice[j]
|
||||
if comparator.Compare(slice[i], slice[j]) == -1 {
|
||||
temp = append(temp, slice[i])
|
||||
i++
|
||||
} else {
|
||||
temp = append(temp, slice[j])
|
||||
j++
|
||||
}
|
||||
}
|
||||
|
||||
if i <= midIndex {
|
||||
temp = append(temp, slice[i:midIndex+1]...)
|
||||
} else {
|
||||
temp = append(temp, slice[j:highIndex+1]...)
|
||||
}
|
||||
|
||||
for k := 0; k < len(temp); k++ {
|
||||
slice[lowIndex+k] = temp[k]
|
||||
}
|
||||
}
|
||||
|
||||
// CountSort use count sorting for slice
|
||||
func CountSort[T any](slice []T, comparator lancetconstraints.Comparator) []T {
|
||||
size := len(slice)
|
||||
out := make([]T, size)
|
||||
|
||||
for i := 0; i < size; i++ {
|
||||
count := 0
|
||||
for j := 0; j < size; j++ {
|
||||
//slice[i] > slice[j]
|
||||
if comparator.Compare(slice[i], slice[j]) == 1 {
|
||||
count++
|
||||
}
|
||||
}
|
||||
out[count] = slice[i]
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
// swap two slice value at index i and j
|
||||
func swap[T any](slice []T, i, j int) {
|
||||
slice[i], slice[j] = slice[j], slice[i]
|
||||
}
|
||||
177
algorithm/sorter_test.go
Normal file
177
algorithm/sorter_test.go
Normal file
@@ -0,0 +1,177 @@
|
||||
package algorithm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
// People test mock data
|
||||
type people struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
// PeopleAageComparator sort people slice by age field
|
||||
type peopleAgeComparator struct{}
|
||||
|
||||
// Compare implements github.com/duke-git/lancet/v2/lancetconstraints/constraints.go/Comparator
|
||||
func (pc *peopleAgeComparator) Compare(v1 any, v2 any) int {
|
||||
p1, _ := v1.(people)
|
||||
p2, _ := v2.(people)
|
||||
|
||||
//ascending order
|
||||
if p1.Age < p2.Age {
|
||||
return -1
|
||||
} else if p1.Age > p2.Age {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
|
||||
//decending order
|
||||
// if p1.Age > p2.Age {
|
||||
// return -1
|
||||
// } else if p1.Age < p2.Age {
|
||||
// return 1
|
||||
// }
|
||||
}
|
||||
|
||||
var peoples = []people{
|
||||
{Name: "a", Age: 20},
|
||||
{Name: "b", Age: 10},
|
||||
{Name: "c", Age: 17},
|
||||
{Name: "d", Age: 8},
|
||||
{Name: "e", Age: 28},
|
||||
}
|
||||
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var intSlice = []int{2, 1, 5, 3, 6, 4}
|
||||
|
||||
func TestBubbleSortForStructSlice(t *testing.T) {
|
||||
asssert := internal.NewAssert(t, "TestBubbleSortForStructSlice")
|
||||
|
||||
comparator := &peopleAgeComparator{}
|
||||
sortedPeopleByAge := BubbleSort(peoples, comparator)
|
||||
t.Log(sortedPeopleByAge)
|
||||
|
||||
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
|
||||
actual := fmt.Sprintf("%v", sortedPeopleByAge)
|
||||
|
||||
asssert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestBubbleSortForIntSlice(t *testing.T) {
|
||||
asssert := internal.NewAssert(t, "TestBubbleSortForIntSlice")
|
||||
|
||||
comparator := &intComparator{}
|
||||
sortedInt := BubbleSort(intSlice, comparator)
|
||||
expected := []int{1, 2, 3, 4, 5, 6}
|
||||
|
||||
asssert.Equal(expected, sortedInt)
|
||||
}
|
||||
|
||||
func TestInsertionSort(t *testing.T) {
|
||||
asssert := internal.NewAssert(t, "TestInsertionSort")
|
||||
|
||||
comparator := &peopleAgeComparator{}
|
||||
sortedPeopleByAge := InsertionSort(peoples, comparator)
|
||||
t.Log(sortedPeopleByAge)
|
||||
|
||||
expected := "[{e 28} {a 20} {c 17} {b 10} {d 8}]"
|
||||
actual := fmt.Sprintf("%v", sortedPeopleByAge)
|
||||
|
||||
asssert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestSelectionSort(t *testing.T) {
|
||||
asssert := internal.NewAssert(t, "TestSelectionSort")
|
||||
|
||||
comparator := &peopleAgeComparator{}
|
||||
sortedPeopleByAge := SelectionSort(peoples, comparator)
|
||||
t.Log(sortedPeopleByAge)
|
||||
|
||||
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
|
||||
actual := fmt.Sprintf("%v", sortedPeopleByAge)
|
||||
|
||||
asssert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestShellSort(t *testing.T) {
|
||||
asssert := internal.NewAssert(t, "TestShellSort")
|
||||
|
||||
comparator := &peopleAgeComparator{}
|
||||
sortedPeopleByAge := ShellSort(peoples, comparator)
|
||||
t.Log(sortedPeopleByAge)
|
||||
|
||||
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
|
||||
actual := fmt.Sprintf("%v", sortedPeopleByAge)
|
||||
|
||||
asssert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestQuickSort(t *testing.T) {
|
||||
asssert := internal.NewAssert(t, "TestQuickSort")
|
||||
|
||||
comparator := &peopleAgeComparator{}
|
||||
sortedPeopleByAge := QuickSort(peoples, 0, len(peoples)-1, comparator)
|
||||
t.Log(sortedPeopleByAge)
|
||||
|
||||
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
|
||||
actual := fmt.Sprintf("%v", sortedPeopleByAge)
|
||||
|
||||
asssert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestHeapSort(t *testing.T) {
|
||||
asssert := internal.NewAssert(t, "TestHeapSort")
|
||||
|
||||
comparator := &peopleAgeComparator{}
|
||||
sortedPeopleByAge := HeapSort(peoples, comparator)
|
||||
t.Log(sortedPeopleByAge)
|
||||
|
||||
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
|
||||
actual := fmt.Sprintf("%v", sortedPeopleByAge)
|
||||
|
||||
asssert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestMergeSort(t *testing.T) {
|
||||
asssert := internal.NewAssert(t, "TestMergeSort")
|
||||
|
||||
comparator := &peopleAgeComparator{}
|
||||
sortedPeopleByAge := MergeSort(peoples, 0, len(peoples)-1, comparator)
|
||||
t.Log(sortedPeopleByAge)
|
||||
|
||||
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
|
||||
actual := fmt.Sprintf("%v", sortedPeopleByAge)
|
||||
|
||||
asssert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestCountSort(t *testing.T) {
|
||||
asssert := internal.NewAssert(t, "TestCountSort")
|
||||
|
||||
comparator := &peopleAgeComparator{}
|
||||
sortedPeopleByAge := CountSort(peoples, comparator)
|
||||
t.Log(sortedPeopleByAge)
|
||||
|
||||
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
|
||||
actual := fmt.Sprintf("%v", sortedPeopleByAge)
|
||||
|
||||
asssert.Equal(expected, actual)
|
||||
}
|
||||
@@ -6,9 +6,10 @@ package convertor
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
@@ -21,14 +22,44 @@ func ToBool(s string) (bool, error) {
|
||||
}
|
||||
|
||||
// ToBytes convert interface to bytes
|
||||
func ToBytes(data interface{}) ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
enc := gob.NewEncoder(&buf)
|
||||
err := enc.Encode(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func ToBytes(value any) ([]byte, error) {
|
||||
v := reflect.ValueOf(value)
|
||||
|
||||
switch value.(type) {
|
||||
case int, int8, int16, int32, int64:
|
||||
number := v.Int()
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
buf.Reset()
|
||||
err := binary.Write(buf, binary.BigEndian, number)
|
||||
return buf.Bytes(), err
|
||||
case uint, uint8, uint16, uint32, uint64:
|
||||
number := v.Uint()
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
buf.Reset()
|
||||
err := binary.Write(buf, binary.BigEndian, number)
|
||||
return buf.Bytes(), err
|
||||
case float32:
|
||||
number := float32(v.Float())
|
||||
bits := math.Float32bits(number)
|
||||
bytes := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(bytes, bits)
|
||||
return bytes, nil
|
||||
case float64:
|
||||
number := v.Float()
|
||||
bits := math.Float64bits(number)
|
||||
bytes := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(bytes, bits)
|
||||
return bytes, nil
|
||||
case bool:
|
||||
return strconv.AppendBool([]byte{}, v.Bool()), nil
|
||||
case string:
|
||||
return []byte(v.String()), nil
|
||||
case []byte:
|
||||
return v.Bytes(), nil
|
||||
default:
|
||||
newValue, err := json.Marshal(value)
|
||||
return newValue, err
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// ToChar convert string to char slice
|
||||
@@ -44,7 +75,7 @@ func ToChar(s string) []string {
|
||||
}
|
||||
|
||||
// ToString convert value to string
|
||||
func ToString(value interface{}) string {
|
||||
func ToString(value any) string {
|
||||
res := ""
|
||||
if value == nil {
|
||||
return res
|
||||
@@ -76,7 +107,7 @@ func ToString(value interface{}) string {
|
||||
}
|
||||
|
||||
// ToJson convert value to a valid json string
|
||||
func ToJson(value interface{}) (string, error) {
|
||||
func ToJson(value any) (string, error) {
|
||||
res, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -86,7 +117,7 @@ func ToJson(value interface{}) (string, error) {
|
||||
}
|
||||
|
||||
// ToFloat convert value to a float64, if input is not a float return 0.0 and error
|
||||
func ToFloat(value interface{}) (float64, error) {
|
||||
func ToFloat(value any) (float64, error) {
|
||||
v := reflect.ValueOf(value)
|
||||
|
||||
res := 0.0
|
||||
@@ -113,7 +144,7 @@ func ToFloat(value interface{}) (float64, error) {
|
||||
}
|
||||
|
||||
// ToInt convert value to a int64, if input is not a numeric format return 0 and error
|
||||
func ToInt(value interface{}) (int64, error) {
|
||||
func ToInt(value any) (int64, error) {
|
||||
v := reflect.ValueOf(value)
|
||||
|
||||
var res int64
|
||||
@@ -141,7 +172,7 @@ func ToInt(value interface{}) (int64, error) {
|
||||
|
||||
// StructToMap convert struct to map, only convert exported struct field
|
||||
// map key is specified same as struct field tag `json` value
|
||||
func StructToMap(value interface{}) (map[string]interface{}, error) {
|
||||
func StructToMap(value any) (map[string]any, error) {
|
||||
v := reflect.ValueOf(value)
|
||||
t := reflect.TypeOf(value)
|
||||
|
||||
@@ -152,7 +183,7 @@ func StructToMap(value interface{}) (map[string]interface{}, error) {
|
||||
return nil, fmt.Errorf("data type %T not support, shuld be struct or pointer to struct", value)
|
||||
}
|
||||
|
||||
res := make(map[string]interface{})
|
||||
res := make(map[string]any)
|
||||
|
||||
fieldNum := t.NumField()
|
||||
pattern := `^[A-Z]`
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/internal"
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestToChar(t *testing.T) {
|
||||
@@ -24,8 +24,8 @@ func TestToChar(t *testing.T) {
|
||||
func TestToBool(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestToBool")
|
||||
|
||||
cases := []string{"true", "True", "false", "False", "0", "1", "123"}
|
||||
expected := []bool{true, true, false, false, false, true, false}
|
||||
cases := []string{"1", "true", "True", "false", "False", "0", "123", "0.0", "abc"}
|
||||
expected := []bool{true, true, true, false, false, false, false, false, false}
|
||||
|
||||
for i := 0; i < len(cases); i++ {
|
||||
actual, _ := ToBool(cases[i])
|
||||
@@ -36,26 +36,33 @@ func TestToBool(t *testing.T) {
|
||||
func TestToBytes(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestToBytes")
|
||||
|
||||
cases := []interface{}{
|
||||
cases := []any{
|
||||
0,
|
||||
false,
|
||||
"1",
|
||||
}
|
||||
expected := [][]byte{
|
||||
{3, 4, 0, 0},
|
||||
{3, 2, 0, 0},
|
||||
{4, 12, 0, 1, 49},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{102, 97, 108, 115, 101},
|
||||
{49},
|
||||
}
|
||||
for i := 0; i < len(cases); i++ {
|
||||
actual, _ := ToBytes(cases[i])
|
||||
assert.Equal(expected[i], actual)
|
||||
}
|
||||
|
||||
bytesData, err := ToBytes("abc")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.Fail()
|
||||
}
|
||||
assert.Equal("abc", ToString(bytesData))
|
||||
}
|
||||
|
||||
func TestToInt(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestToInt")
|
||||
|
||||
cases := []interface{}{"123", "-123", 123,
|
||||
cases := []any{"123", "-123", 123,
|
||||
uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
|
||||
float32(12.3), float64(12.3),
|
||||
"abc", false, "111111111111111111111111111111111111111"}
|
||||
@@ -71,7 +78,7 @@ func TestToInt(t *testing.T) {
|
||||
func TestToFloat(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestToFloat")
|
||||
|
||||
cases := []interface{}{
|
||||
cases := []any{
|
||||
"", "-1", "-.11", "1.23e3", ".123e10", "abc",
|
||||
int(0), int8(1), int16(-1), int32(123), int64(123),
|
||||
uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
|
||||
@@ -99,7 +106,7 @@ func TestToString(t *testing.T) {
|
||||
}
|
||||
aStruct := TestStruct{Name: "TestStruct"}
|
||||
|
||||
cases := []interface{}{
|
||||
cases := []any{
|
||||
"", nil,
|
||||
int(0), int8(1), int16(-1), int32(123), int64(123),
|
||||
uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
|
||||
@@ -147,7 +154,7 @@ func TestStructToMap(t *testing.T) {
|
||||
100,
|
||||
}
|
||||
pm, _ := StructToMap(p)
|
||||
var expected = map[string]interface{}{"name": "test"}
|
||||
var expected = map[string]any{"name": "test"}
|
||||
assert.Equal(expected, pm)
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package cryptor
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/internal"
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestAesEcbEncrypt(t *testing.T) {
|
||||
|
||||
@@ -3,7 +3,7 @@ package cryptor
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/internal"
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestBase64StdEncode(t *testing.T) {
|
||||
|
||||
@@ -19,10 +19,12 @@ func DesEcbEncrypt(data, key []byte) []byte {
|
||||
length := (len(data) + des.BlockSize) / des.BlockSize
|
||||
plain := make([]byte, length*des.BlockSize)
|
||||
copy(plain, data)
|
||||
|
||||
pad := byte(len(plain) - len(data))
|
||||
for i := len(data); i < len(plain); i++ {
|
||||
plain[i] = pad
|
||||
}
|
||||
|
||||
encrypted := make([]byte, len(plain))
|
||||
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])
|
||||
@@ -36,7 +38,7 @@ func DesEcbEncrypt(data, key []byte) []byte {
|
||||
func DesEcbDecrypt(encrypted, key []byte) []byte {
|
||||
cipher, _ := des.NewCipher(generateDesKey(key))
|
||||
decrypted := make([]byte, len(encrypted))
|
||||
//
|
||||
|
||||
for bs, be := 0, cipher.BlockSize(); bs < len(encrypted); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
|
||||
cipher.Decrypt(decrypted[bs:be], encrypted[bs:be])
|
||||
}
|
||||
@@ -59,6 +61,7 @@ func DesCbcEncrypt(data, key []byte) []byte {
|
||||
|
||||
encrypted := make([]byte, len(data))
|
||||
blockMode.CryptBlocks(encrypted, data)
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
@@ -72,6 +75,7 @@ func DesCbcDecrypt(encrypted, key []byte) []byte {
|
||||
decrypted := make([]byte, len(encrypted))
|
||||
blockMode.CryptBlocks(decrypted, encrypted)
|
||||
decrypted = pkcs7UnPadding(decrypted)
|
||||
|
||||
return decrypted
|
||||
}
|
||||
|
||||
@@ -105,6 +109,7 @@ func DesCfbEncrypt(data, key []byte) []byte {
|
||||
|
||||
stream := cipher.NewCFBEncrypter(block, iv)
|
||||
stream.XORKeyStream(encrypted[des.BlockSize:], data)
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
@@ -120,6 +125,7 @@ func DesCfbDecrypt(encrypted, key []byte) []byte {
|
||||
|
||||
stream := cipher.NewCFBDecrypter(block, iv)
|
||||
stream.XORKeyStream(encrypted, encrypted)
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
@@ -139,6 +145,7 @@ func DesOfbEncrypt(data, key []byte) []byte {
|
||||
|
||||
stream := cipher.NewOFB(block, iv)
|
||||
stream.XORKeyStream(encrypted[des.BlockSize:], data)
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
@@ -161,6 +168,6 @@ func DesOfbDecrypt(data, key []byte) []byte {
|
||||
mode.XORKeyStream(decrypted, data)
|
||||
|
||||
decrypted = pkcs7UnPadding(decrypted)
|
||||
return decrypted
|
||||
|
||||
return decrypted
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package cryptor
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/internal"
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestDesEcbEncrypt(t *testing.T) {
|
||||
|
||||
@@ -14,11 +14,11 @@ import (
|
||||
|
||||
// GenerateRsaKey make a rsa private key, and return key file name
|
||||
// Generated key file is `rsa_private.pem` and `rsa_public.pem` in current path
|
||||
func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) {
|
||||
func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) error {
|
||||
// private key
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, keySize)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return err
|
||||
}
|
||||
|
||||
derText := x509.MarshalPKCS1PrivateKey(privateKey)
|
||||
@@ -41,7 +41,7 @@ func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) {
|
||||
|
||||
derpText, err := x509.MarshalPKIXPublicKey(&publicKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return err
|
||||
}
|
||||
|
||||
block = pem.Block{
|
||||
@@ -52,10 +52,12 @@ func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) {
|
||||
//file,err = os.Create("rsa_public.pem")
|
||||
file, err = os.Create(pubKeyFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return err
|
||||
}
|
||||
pem.Encode(file, &block)
|
||||
file.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RsaEncrypt encrypt data with ras algorithm
|
||||
|
||||
@@ -3,11 +3,14 @@ package cryptor
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/internal"
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestRsaEncrypt(t *testing.T) {
|
||||
GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
|
||||
err := GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
|
||||
if err != nil {
|
||||
t.FailNow()
|
||||
}
|
||||
data := []byte("hello world")
|
||||
encrypted := RsaEncrypt(data, "rsa_public.pem")
|
||||
decrypted := RsaDecrypt(encrypted, "rsa_private.pem")
|
||||
|
||||
241
datastructure/link/doublylink.go
Normal file
241
datastructure/link/doublylink.go
Normal file
@@ -0,0 +1,241 @@
|
||||
package datastructure
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/duke-git/lancet/v2/datastructure"
|
||||
)
|
||||
|
||||
// DoublyLink is a linked list. Whose node has a generic Value, Pre pointer points to a previous node of the link, Next pointer points to a next node of the link.
|
||||
type DoublyLink[T any] struct {
|
||||
Head *datastructure.LinkNode[T]
|
||||
length int
|
||||
}
|
||||
|
||||
// NewDoublyLink return *DoublyLink instance
|
||||
func NewDoublyLink[T any]() *DoublyLink[T] {
|
||||
return &DoublyLink[T]{Head: nil}
|
||||
}
|
||||
|
||||
// InsertAtHead insert value into doubly linklist at head index
|
||||
func (link *DoublyLink[T]) InsertAtHead(value T) {
|
||||
newNode := datastructure.NewLinkNode(value)
|
||||
size := link.Size()
|
||||
|
||||
if size == 0 {
|
||||
link.Head = newNode
|
||||
link.length++
|
||||
return
|
||||
}
|
||||
|
||||
newNode.Next = link.Head
|
||||
newNode.Pre = nil
|
||||
|
||||
link.Head.Pre = newNode
|
||||
link.Head = newNode
|
||||
|
||||
link.length++
|
||||
}
|
||||
|
||||
// InsertAtTail insert value into doubly linklist at tail index
|
||||
func (link *DoublyLink[T]) InsertAtTail(value T) {
|
||||
current := link.Head
|
||||
if current == nil {
|
||||
link.InsertAtHead(value)
|
||||
return
|
||||
}
|
||||
|
||||
for current.Next != nil {
|
||||
current = current.Next
|
||||
}
|
||||
|
||||
newNode := datastructure.NewLinkNode(value)
|
||||
newNode.Next = nil
|
||||
newNode.Pre = current
|
||||
current.Next = newNode
|
||||
|
||||
link.length++
|
||||
}
|
||||
|
||||
// InsertAt insert value into doubly linklist at index
|
||||
func (link *DoublyLink[T]) InsertAt(index int, value T) error {
|
||||
size := link.length
|
||||
if index < 0 || index > size {
|
||||
return errors.New("param index should between 0 and the length of doubly link.")
|
||||
}
|
||||
|
||||
if index == 0 {
|
||||
link.InsertAtHead(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
if index == size {
|
||||
link.InsertAtTail(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
i := 0
|
||||
current := link.Head
|
||||
|
||||
for current != nil {
|
||||
if i == index-1 {
|
||||
newNode := datastructure.NewLinkNode(value)
|
||||
newNode.Next = current.Next
|
||||
newNode.Pre = current
|
||||
|
||||
current.Next = newNode
|
||||
link.length++
|
||||
|
||||
return nil
|
||||
}
|
||||
i++
|
||||
current = current.Next
|
||||
}
|
||||
|
||||
return errors.New("doubly link list no exist")
|
||||
}
|
||||
|
||||
// DeleteAtHead delete value in doubly linklist at head index
|
||||
func (link *DoublyLink[T]) DeleteAtHead() error {
|
||||
if link.Head == nil {
|
||||
return errors.New("doubly link list no exist")
|
||||
}
|
||||
current := link.Head
|
||||
link.Head = current.Next
|
||||
link.Head.Pre = nil
|
||||
link.length--
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteAtTail delete value in doubly linklist at tail index
|
||||
func (link *DoublyLink[T]) DeleteAtTail() error {
|
||||
if link.Head == nil {
|
||||
return errors.New("doubly link list no exist")
|
||||
}
|
||||
current := link.Head
|
||||
if current.Next == nil {
|
||||
return link.DeleteAtHead()
|
||||
}
|
||||
|
||||
for current.Next.Next != nil {
|
||||
current = current.Next
|
||||
}
|
||||
|
||||
current.Next = nil
|
||||
link.length--
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteAt delete value in doubly linklist at index
|
||||
func (link *DoublyLink[T]) DeleteAt(index int) error {
|
||||
if link.Head == nil {
|
||||
return errors.New("doubly link list no exist")
|
||||
}
|
||||
current := link.Head
|
||||
if current.Next == nil || index == 0 {
|
||||
return link.DeleteAtHead()
|
||||
}
|
||||
|
||||
if index == link.length-1 {
|
||||
return link.DeleteAtTail()
|
||||
}
|
||||
|
||||
if index < 0 || index > link.length-1 {
|
||||
return errors.New("param index should between 0 and link size -1.")
|
||||
}
|
||||
|
||||
i := 0
|
||||
for current != nil {
|
||||
if i == index-1 {
|
||||
current.Next = current.Next.Next
|
||||
link.length--
|
||||
return nil
|
||||
}
|
||||
i++
|
||||
current = current.Next
|
||||
}
|
||||
|
||||
return errors.New("delete error")
|
||||
}
|
||||
|
||||
// Reverse the linked list
|
||||
func (link *DoublyLink[T]) Reverse() {
|
||||
current := link.Head
|
||||
var temp *datastructure.LinkNode[T]
|
||||
|
||||
for current != nil {
|
||||
temp = current.Pre
|
||||
current.Pre = current.Next
|
||||
current.Next = temp
|
||||
current = current.Pre
|
||||
}
|
||||
|
||||
if temp != nil {
|
||||
link.Head = temp.Pre
|
||||
}
|
||||
}
|
||||
|
||||
// GetMiddleNode return node at middle index of linked list
|
||||
func (link *DoublyLink[T]) GetMiddleNode() *datastructure.LinkNode[T] {
|
||||
if link.Head == nil {
|
||||
return nil
|
||||
}
|
||||
if link.Head.Next == nil {
|
||||
return link.Head
|
||||
}
|
||||
fast := link.Head
|
||||
slow := link.Head
|
||||
|
||||
for fast != nil {
|
||||
fast = fast.Next
|
||||
|
||||
if fast != nil {
|
||||
fast = fast.Next
|
||||
slow = slow.Next
|
||||
} else {
|
||||
return slow
|
||||
}
|
||||
}
|
||||
return slow
|
||||
}
|
||||
|
||||
// Size return the count of doubly linked list
|
||||
func (link *DoublyLink[T]) Size() int {
|
||||
return link.length
|
||||
}
|
||||
|
||||
// Values return slice of all doubly linklist node value
|
||||
func (link *DoublyLink[T]) Values() []T {
|
||||
res := []T{}
|
||||
current := link.Head
|
||||
for current != nil {
|
||||
res = append(res, current.Value)
|
||||
current = current.Next
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Print all nodes info of a linked list
|
||||
func (link *DoublyLink[T]) Print() {
|
||||
current := link.Head
|
||||
info := "[ "
|
||||
for current != nil {
|
||||
info += fmt.Sprintf("%+v, ", current)
|
||||
current = current.Next
|
||||
}
|
||||
info += " ]"
|
||||
fmt.Println(info)
|
||||
}
|
||||
|
||||
// IsEmpty checks if link is empty or not
|
||||
func (link *DoublyLink[T]) IsEmpty() bool {
|
||||
return link.length == 0
|
||||
}
|
||||
|
||||
// Clear checks if link is empty or not
|
||||
func (link *DoublyLink[T]) Clear() {
|
||||
link.Head = nil
|
||||
link.length = 0
|
||||
}
|
||||
179
datastructure/link/doublylink_test.go
Normal file
179
datastructure/link/doublylink_test.go
Normal file
@@ -0,0 +1,179 @@
|
||||
package datastructure
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestDoublyLink_InsertAtFirst(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestDoublyLink_InsertAtFirst")
|
||||
|
||||
link := NewDoublyLink[int]()
|
||||
link.InsertAtHead(1)
|
||||
link.InsertAtHead(2)
|
||||
link.InsertAtHead(3)
|
||||
link.Print()
|
||||
|
||||
expected := []int{3, 2, 1}
|
||||
values := link.Values()
|
||||
|
||||
assert.Equal(expected, values)
|
||||
}
|
||||
|
||||
func TestDoublyLink_InsertAtTail(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestDoublyLink_InsertAtTail")
|
||||
|
||||
link := NewDoublyLink[int]()
|
||||
link.InsertAtTail(1)
|
||||
link.InsertAtTail(2)
|
||||
link.InsertAtTail(3)
|
||||
link.Print()
|
||||
|
||||
expected := []int{1, 2, 3}
|
||||
values := link.Values()
|
||||
|
||||
assert.Equal(expected, values)
|
||||
}
|
||||
|
||||
func TestDoublyLink_InsertAt(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestDoublyLink_InsertAt")
|
||||
|
||||
link := NewDoublyLink[int]()
|
||||
|
||||
err := link.InsertAt(1, 1)
|
||||
assert.IsNotNil(err)
|
||||
|
||||
link.InsertAt(0, 1)
|
||||
link.InsertAt(1, 2)
|
||||
link.InsertAt(2, 4)
|
||||
link.InsertAt(2, 3)
|
||||
|
||||
link.Print()
|
||||
|
||||
expected := []int{1, 2, 3, 4}
|
||||
values := link.Values()
|
||||
|
||||
assert.Equal(expected, values)
|
||||
|
||||
}
|
||||
|
||||
func TestDoublyLink_DeleteAtHead(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestDoublyLink_DeleteAtHead")
|
||||
|
||||
link := NewDoublyLink[int]()
|
||||
err := link.DeleteAtHead()
|
||||
assert.IsNotNil(err)
|
||||
|
||||
link.InsertAtTail(1)
|
||||
link.InsertAtTail(2)
|
||||
link.InsertAtTail(3)
|
||||
link.InsertAtTail(4)
|
||||
|
||||
link.DeleteAtHead()
|
||||
link.Print()
|
||||
|
||||
expected := []int{2, 3, 4}
|
||||
values := link.Values()
|
||||
|
||||
assert.Equal(expected, values)
|
||||
}
|
||||
|
||||
func TestDoublyLink_DeleteAtTail(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestDoublyLink_DeleteAtTail")
|
||||
|
||||
link := NewDoublyLink[int]()
|
||||
err := link.DeleteAtTail()
|
||||
assert.IsNotNil(err)
|
||||
|
||||
link.InsertAtTail(1)
|
||||
link.InsertAtTail(2)
|
||||
link.InsertAtTail(3)
|
||||
link.InsertAtTail(4)
|
||||
|
||||
link.DeleteAtTail()
|
||||
link.Print()
|
||||
|
||||
expected := []int{1, 2, 3}
|
||||
values := link.Values()
|
||||
|
||||
assert.Equal(expected, values)
|
||||
}
|
||||
|
||||
func TestDoublyLink_DeleteAt(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestDoublyLink_DeleteAt")
|
||||
|
||||
link := NewDoublyLink[int]()
|
||||
err := link.DeleteAt(0)
|
||||
assert.IsNotNil(err)
|
||||
|
||||
link.InsertAtTail(1)
|
||||
link.InsertAtTail(2)
|
||||
link.InsertAtTail(3)
|
||||
link.InsertAtTail(4)
|
||||
link.InsertAtTail(5)
|
||||
|
||||
err = link.DeleteAt(5)
|
||||
assert.IsNotNil(err)
|
||||
|
||||
err = link.DeleteAt(0)
|
||||
assert.IsNil(err)
|
||||
assert.Equal([]int{2, 3, 4, 5}, link.Values())
|
||||
|
||||
link.DeleteAt(3)
|
||||
assert.Equal([]int{2, 3, 4}, link.Values())
|
||||
|
||||
link.DeleteAt(1)
|
||||
assert.Equal(2, link.Size())
|
||||
assert.Equal([]int{2, 4}, link.Values())
|
||||
}
|
||||
|
||||
func TestDoublyLink_Reverse(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestDoublyLink_Reverse")
|
||||
|
||||
link := NewDoublyLink[int]()
|
||||
link.InsertAtTail(1)
|
||||
link.InsertAtTail(2)
|
||||
link.InsertAtTail(3)
|
||||
link.InsertAtTail(4)
|
||||
|
||||
link.Reverse()
|
||||
link.Print()
|
||||
assert.Equal([]int{4, 3, 2, 1}, link.Values())
|
||||
}
|
||||
|
||||
func TestDoublyLink_GetMiddleNode(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestDoublyLink_GetMiddleNode")
|
||||
|
||||
link := NewDoublyLink[int]()
|
||||
link.InsertAtTail(1)
|
||||
link.InsertAtTail(2)
|
||||
link.InsertAtTail(3)
|
||||
link.InsertAtTail(4)
|
||||
|
||||
middle1 := link.GetMiddleNode()
|
||||
assert.Equal(3, middle1.Value)
|
||||
|
||||
link.InsertAtTail(5)
|
||||
link.InsertAtTail(6)
|
||||
link.InsertAtTail(7)
|
||||
middle2 := link.GetMiddleNode()
|
||||
assert.Equal(4, middle2.Value)
|
||||
}
|
||||
|
||||
func TestDoublyLink_Clear(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestDoublyLink_Clear")
|
||||
|
||||
link := NewDoublyLink[int]()
|
||||
|
||||
assert.Equal(true, link.IsEmpty())
|
||||
assert.Equal(0, link.Size())
|
||||
|
||||
link.InsertAtTail(1)
|
||||
assert.Equal(false, link.IsEmpty())
|
||||
assert.Equal(1, link.Size())
|
||||
|
||||
link.Clear()
|
||||
assert.Equal(true, link.IsEmpty())
|
||||
assert.Equal(0, link.Size())
|
||||
}
|
||||
246
datastructure/link/singlylink.go
Normal file
246
datastructure/link/singlylink.go
Normal file
@@ -0,0 +1,246 @@
|
||||
package datastructure
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/duke-git/lancet/v2/datastructure"
|
||||
)
|
||||
|
||||
// SinglyLink is a linked list. Whose node has a Value generics and Next pointer points to a next node of the link.
|
||||
type SinglyLink[T any] struct {
|
||||
Head *datastructure.LinkNode[T]
|
||||
length int
|
||||
}
|
||||
|
||||
// NewSinglyLink return *SinglyLink instance
|
||||
func NewSinglyLink[T any]() *SinglyLink[T] {
|
||||
return &SinglyLink[T]{Head: nil}
|
||||
}
|
||||
|
||||
// InsertAtHead insert value into singly linklist at head index
|
||||
func (link *SinglyLink[T]) InsertAtHead(value T) {
|
||||
newNode := datastructure.NewLinkNode(value)
|
||||
newNode.Next = link.Head
|
||||
link.Head = newNode
|
||||
link.length++
|
||||
}
|
||||
|
||||
// InsertAtTail insert value into singly linklist at tail index
|
||||
func (link *SinglyLink[T]) InsertAtTail(value T) {
|
||||
current := link.Head
|
||||
if current == nil {
|
||||
link.InsertAtHead(value)
|
||||
return
|
||||
}
|
||||
|
||||
for current.Next != nil {
|
||||
current = current.Next
|
||||
}
|
||||
|
||||
newNode := datastructure.NewLinkNode(value)
|
||||
newNode.Next = nil
|
||||
current.Next = newNode
|
||||
|
||||
link.length++
|
||||
}
|
||||
|
||||
// InsertAt insert value into singly linklist at index
|
||||
func (link *SinglyLink[T]) InsertAt(index int, value T) error {
|
||||
size := link.length
|
||||
if index < 0 || index > size {
|
||||
return errors.New("param index should between 0 and the length of singly link.")
|
||||
}
|
||||
|
||||
if index == 0 {
|
||||
link.InsertAtHead(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
if index == size {
|
||||
link.InsertAtTail(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
i := 0
|
||||
current := link.Head
|
||||
|
||||
for current != nil {
|
||||
if i == index-1 {
|
||||
newNode := datastructure.NewLinkNode(value)
|
||||
newNode.Next = current.Next
|
||||
current.Next = newNode
|
||||
link.length++
|
||||
|
||||
return nil
|
||||
}
|
||||
i++
|
||||
current = current.Next
|
||||
}
|
||||
|
||||
return errors.New("singly link list no exist")
|
||||
}
|
||||
|
||||
// DeleteAtHead delete value in singly linklist at head index
|
||||
func (link *SinglyLink[T]) DeleteAtHead() error {
|
||||
if link.Head == nil {
|
||||
return errors.New("singly link list no exist")
|
||||
}
|
||||
current := link.Head
|
||||
link.Head = current.Next
|
||||
link.length--
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteAtTail delete value in singly linklist at tail index
|
||||
func (link *SinglyLink[T]) DeleteAtTail() error {
|
||||
if link.Head == nil {
|
||||
return errors.New("singly link list no exist")
|
||||
}
|
||||
current := link.Head
|
||||
if current.Next == nil {
|
||||
return link.DeleteAtHead()
|
||||
}
|
||||
|
||||
for current.Next.Next != nil {
|
||||
current = current.Next
|
||||
}
|
||||
|
||||
current.Next = nil
|
||||
link.length--
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteAt delete value in singly linklist at index
|
||||
func (link *SinglyLink[T]) DeleteAt(index int) error {
|
||||
if link.Head == nil {
|
||||
return errors.New("singly link list no exist")
|
||||
}
|
||||
current := link.Head
|
||||
if current.Next == nil || index == 0 {
|
||||
return link.DeleteAtHead()
|
||||
}
|
||||
|
||||
if index == link.length-1 {
|
||||
return link.DeleteAtTail()
|
||||
}
|
||||
|
||||
if index < 0 || index > link.length-1 {
|
||||
return errors.New("param index should between 0 and link size -1.")
|
||||
}
|
||||
|
||||
i := 0
|
||||
for current != nil {
|
||||
if i == index-1 {
|
||||
current.Next = current.Next.Next
|
||||
link.length--
|
||||
return nil
|
||||
}
|
||||
i++
|
||||
current = current.Next
|
||||
}
|
||||
|
||||
return errors.New("delete error")
|
||||
}
|
||||
|
||||
// DeleteValue delete value in singly linklist
|
||||
func (link *SinglyLink[T]) DeleteValue(value T) {
|
||||
if link.Head == nil {
|
||||
return
|
||||
}
|
||||
dummyHead := datastructure.NewLinkNode(value)
|
||||
dummyHead.Next = link.Head
|
||||
current := dummyHead
|
||||
|
||||
for current.Next != nil {
|
||||
if reflect.DeepEqual(current.Next.Value, value) {
|
||||
current.Next = current.Next.Next
|
||||
link.length--
|
||||
} else {
|
||||
current = current.Next
|
||||
}
|
||||
}
|
||||
|
||||
link.Head = dummyHead.Next
|
||||
}
|
||||
|
||||
// Reverse the linked list
|
||||
func (link *SinglyLink[T]) Reverse() {
|
||||
var pre, next *datastructure.LinkNode[T]
|
||||
|
||||
current := link.Head
|
||||
|
||||
for current != nil {
|
||||
next = current.Next
|
||||
current.Next = pre
|
||||
pre = current
|
||||
current = next
|
||||
}
|
||||
|
||||
link.Head = pre
|
||||
}
|
||||
|
||||
// GetMiddleNode return node at middle index of linked list
|
||||
func (link *SinglyLink[T]) GetMiddleNode() *datastructure.LinkNode[T] {
|
||||
if link.Head == nil {
|
||||
return nil
|
||||
}
|
||||
if link.Head.Next == nil {
|
||||
return link.Head
|
||||
}
|
||||
fast := link.Head
|
||||
slow := link.Head
|
||||
|
||||
for fast != nil {
|
||||
fast = fast.Next
|
||||
|
||||
if fast != nil {
|
||||
fast = fast.Next
|
||||
slow = slow.Next
|
||||
} else {
|
||||
return slow
|
||||
}
|
||||
}
|
||||
return slow
|
||||
}
|
||||
|
||||
// Size return the count of singly linked list
|
||||
func (link *SinglyLink[T]) Size() int {
|
||||
return link.length
|
||||
}
|
||||
|
||||
// Values return slice of all singly linklist node value
|
||||
func (link *SinglyLink[T]) Values() []T {
|
||||
res := []T{}
|
||||
current := link.Head
|
||||
for current != nil {
|
||||
res = append(res, current.Value)
|
||||
current = current.Next
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// IsEmpty checks if link is empty or not
|
||||
func (link *SinglyLink[T]) IsEmpty() bool {
|
||||
return link.length == 0
|
||||
}
|
||||
|
||||
// Clear checks if link is empty or not
|
||||
func (link *SinglyLink[T]) Clear() {
|
||||
link.Head = nil
|
||||
link.length = 0
|
||||
}
|
||||
|
||||
// Print all nodes info of a linked list
|
||||
func (link *SinglyLink[T]) Print() {
|
||||
current := link.Head
|
||||
info := "[ "
|
||||
for current != nil {
|
||||
info += fmt.Sprintf("%+v, ", current)
|
||||
current = current.Next
|
||||
}
|
||||
info += " ]"
|
||||
fmt.Println(info)
|
||||
}
|
||||
208
datastructure/link/singlylink_test.go
Normal file
208
datastructure/link/singlylink_test.go
Normal file
@@ -0,0 +1,208 @@
|
||||
package datastructure
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestSinglyLink_InsertAtFirst(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSinglyLink_InsertAtFirst")
|
||||
|
||||
link := NewSinglyLink[int]()
|
||||
link.InsertAtHead(1)
|
||||
link.InsertAtHead(2)
|
||||
link.InsertAtHead(3)
|
||||
link.Print()
|
||||
|
||||
expected := []int{3, 2, 1}
|
||||
values := link.Values()
|
||||
|
||||
assert.Equal(expected, values)
|
||||
}
|
||||
|
||||
func TestSinglyLink_InsertAtTail(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSinglyLink_InsertAtTail")
|
||||
|
||||
link := NewSinglyLink[int]()
|
||||
link.InsertAtTail(1)
|
||||
link.InsertAtTail(2)
|
||||
link.InsertAtTail(3)
|
||||
link.Print()
|
||||
|
||||
expected := []int{1, 2, 3}
|
||||
values := link.Values()
|
||||
|
||||
assert.Equal(expected, values)
|
||||
}
|
||||
|
||||
func TestSinglyLink_InsertAt(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSinglyLink_InsertAt")
|
||||
|
||||
link := NewSinglyLink[int]()
|
||||
|
||||
err := link.InsertAt(1, 1)
|
||||
assert.IsNotNil(err)
|
||||
|
||||
err = link.InsertAt(0, 1)
|
||||
if err != nil {
|
||||
t.FailNow()
|
||||
}
|
||||
err = link.InsertAt(1, 2)
|
||||
if err != nil {
|
||||
t.FailNow()
|
||||
}
|
||||
err = link.InsertAt(2, 4)
|
||||
if err != nil {
|
||||
t.FailNow()
|
||||
}
|
||||
err = link.InsertAt(2, 3)
|
||||
if err != nil {
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
link.Print()
|
||||
|
||||
expected := []int{1, 2, 3, 4}
|
||||
values := link.Values()
|
||||
|
||||
assert.Equal(expected, values)
|
||||
}
|
||||
|
||||
func TestSinglyLink_DeleteAtHead(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSinglyLink_DeleteAtHead")
|
||||
|
||||
link := NewSinglyLink[int]()
|
||||
err := link.DeleteAtHead()
|
||||
assert.IsNotNil(err)
|
||||
|
||||
link.InsertAtTail(1)
|
||||
link.InsertAtTail(2)
|
||||
link.InsertAtTail(3)
|
||||
link.InsertAtTail(4)
|
||||
|
||||
link.DeleteAtHead()
|
||||
link.Print()
|
||||
|
||||
expected := []int{2, 3, 4}
|
||||
values := link.Values()
|
||||
|
||||
assert.Equal(expected, values)
|
||||
}
|
||||
|
||||
func TestSinglyLink_DeleteAtTail(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSinglyLink_DeleteAtTail")
|
||||
|
||||
link := NewSinglyLink[int]()
|
||||
err := link.DeleteAtTail()
|
||||
assert.IsNotNil(err)
|
||||
|
||||
link.InsertAtTail(1)
|
||||
link.InsertAtTail(2)
|
||||
link.InsertAtTail(3)
|
||||
link.InsertAtTail(4)
|
||||
|
||||
link.DeleteAtTail()
|
||||
link.Print()
|
||||
|
||||
expected := []int{1, 2, 3}
|
||||
values := link.Values()
|
||||
|
||||
assert.Equal(expected, values)
|
||||
}
|
||||
|
||||
func TestSinglyLink_DeleteValue(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSinglyLink_DeleteValue")
|
||||
|
||||
link := NewSinglyLink[int]()
|
||||
|
||||
link.InsertAtTail(1)
|
||||
link.InsertAtTail(2)
|
||||
link.InsertAtTail(2)
|
||||
link.InsertAtTail(3)
|
||||
link.InsertAtTail(4)
|
||||
|
||||
link.DeleteValue(2)
|
||||
assert.Equal([]int{1, 3, 4}, link.Values())
|
||||
|
||||
link.DeleteValue(1)
|
||||
assert.Equal([]int{3, 4}, link.Values())
|
||||
}
|
||||
|
||||
func TestSinglyLink_DeleteAt(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSinglyLink_DeleteAt")
|
||||
|
||||
link := NewSinglyLink[int]()
|
||||
err := link.DeleteAt(0)
|
||||
assert.IsNotNil(err)
|
||||
|
||||
link.InsertAtTail(1)
|
||||
link.InsertAtTail(2)
|
||||
link.InsertAtTail(3)
|
||||
link.InsertAtTail(4)
|
||||
link.InsertAtTail(5)
|
||||
|
||||
err = link.DeleteAt(5)
|
||||
assert.IsNotNil(err)
|
||||
|
||||
err = link.DeleteAt(0)
|
||||
assert.IsNil(err)
|
||||
assert.Equal([]int{2, 3, 4, 5}, link.Values())
|
||||
|
||||
link.DeleteAt(3)
|
||||
assert.Equal([]int{2, 3, 4}, link.Values())
|
||||
|
||||
link.DeleteAt(1)
|
||||
assert.Equal(2, link.Size())
|
||||
assert.Equal([]int{2, 4}, link.Values())
|
||||
}
|
||||
|
||||
func TestSinglyLink_Reverse(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSinglyLink_Reverse")
|
||||
|
||||
link := NewSinglyLink[int]()
|
||||
link.InsertAtTail(1)
|
||||
link.InsertAtTail(2)
|
||||
link.InsertAtTail(3)
|
||||
link.InsertAtTail(4)
|
||||
|
||||
link.Reverse()
|
||||
link.Print()
|
||||
assert.Equal([]int{4, 3, 2, 1}, link.Values())
|
||||
}
|
||||
|
||||
func TestSinglyLink_GetMiddleNode(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSinglyLink_GetMiddleNode")
|
||||
|
||||
link := NewSinglyLink[int]()
|
||||
link.InsertAtTail(1)
|
||||
link.InsertAtTail(2)
|
||||
link.InsertAtTail(3)
|
||||
link.InsertAtTail(4)
|
||||
|
||||
middle1 := link.GetMiddleNode()
|
||||
assert.Equal(3, middle1.Value)
|
||||
|
||||
link.InsertAtTail(5)
|
||||
link.InsertAtTail(6)
|
||||
link.InsertAtTail(7)
|
||||
middle2 := link.GetMiddleNode()
|
||||
assert.Equal(4, middle2.Value)
|
||||
}
|
||||
|
||||
func TestSinglyLink_Clear(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSinglyLink_Clear")
|
||||
|
||||
link := NewSinglyLink[int]()
|
||||
|
||||
assert.Equal(true, link.IsEmpty())
|
||||
assert.Equal(0, link.Size())
|
||||
|
||||
link.InsertAtTail(1)
|
||||
assert.Equal(false, link.IsEmpty())
|
||||
assert.Equal(1, link.Size())
|
||||
|
||||
link.Clear()
|
||||
assert.Equal(true, link.IsEmpty())
|
||||
assert.Equal(0, link.Size())
|
||||
}
|
||||
245
datastructure/list/list.go
Normal file
245
datastructure/list/list.go
Normal file
@@ -0,0 +1,245 @@
|
||||
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
|
||||
// Use of this source code is governed by MIT license
|
||||
|
||||
// Package datastructure implements some data structure. eg. list, linklist, stack, queue, tree, graph.
|
||||
package datastructure
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// List is a linear table, implemented with slice
|
||||
type List[T any] struct {
|
||||
data []T
|
||||
}
|
||||
|
||||
// NewList return a pointer of List
|
||||
func NewList[T any](data []T) *List[T] {
|
||||
return &List[T]{data: data}
|
||||
}
|
||||
|
||||
// Data return list data
|
||||
func (l *List[T]) Data() []T {
|
||||
return l.data
|
||||
}
|
||||
|
||||
// ValueOf return the value pointer at index of list data.
|
||||
func (l *List[T]) ValueOf(index int) (*T, bool) {
|
||||
if index < 0 || index >= len(l.data) {
|
||||
return nil, false
|
||||
}
|
||||
return &l.data[index], true
|
||||
}
|
||||
|
||||
// IndexOf reture the index of value. if not found return -1
|
||||
func (l *List[T]) IndexOf(value T) int {
|
||||
index := -1
|
||||
data := l.data
|
||||
for i, v := range data {
|
||||
if reflect.DeepEqual(v, value) {
|
||||
index = i
|
||||
break
|
||||
}
|
||||
}
|
||||
return index
|
||||
}
|
||||
|
||||
// Contain checks if the value in the list or not
|
||||
func (l *List[T]) Contain(value T) bool {
|
||||
data := l.data
|
||||
for _, v := range data {
|
||||
if reflect.DeepEqual(v, value) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Push append value to the list data
|
||||
func (l *List[T]) Push(value T) {
|
||||
l.data = append(l.data, value)
|
||||
}
|
||||
|
||||
// InsertAtFirst insert value into list at first index
|
||||
func (l *List[T]) InsertAtFirst(value T) {
|
||||
l.InsertAt(0, value)
|
||||
}
|
||||
|
||||
// InsertAtLast insert value into list at last index
|
||||
func (l *List[T]) InsertAtLast(value T) {
|
||||
l.InsertAt(len(l.data), value)
|
||||
}
|
||||
|
||||
// InsertAt insert value into list at index
|
||||
func (l *List[T]) InsertAt(index int, value T) {
|
||||
data := l.data
|
||||
size := len(data)
|
||||
|
||||
if index < 0 || index > size {
|
||||
return
|
||||
}
|
||||
l.data = append(data[:index], append([]T{value}, data[index:]...)...)
|
||||
}
|
||||
|
||||
// PopFirst delete the first value of list and return it
|
||||
func (l *List[T]) PopFirst() (*T, bool) {
|
||||
if len(l.data) == 0 {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
v := l.data[0]
|
||||
l.DeleteAt(0)
|
||||
|
||||
return &v, true
|
||||
}
|
||||
|
||||
// PopLast delete the last value of list and return it
|
||||
func (l *List[T]) PopLast() (*T, bool) {
|
||||
size := len(l.data)
|
||||
if size == 0 {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
v := l.data[size-1]
|
||||
l.DeleteAt(size - 1)
|
||||
|
||||
return &v, true
|
||||
}
|
||||
|
||||
// DeleteAt delete the value of list at index
|
||||
func (l *List[T]) DeleteAt(index int) {
|
||||
data := l.data
|
||||
size := len(data)
|
||||
if index < 0 || index > size-1 {
|
||||
return
|
||||
}
|
||||
if index == size-1 {
|
||||
data = append(data[:index])
|
||||
} else {
|
||||
data = append(data[:index], data[index+1:]...)
|
||||
}
|
||||
l.data = data
|
||||
}
|
||||
|
||||
// UpdateAt update value of list at index, index shoud between 0 and list size -1
|
||||
func (l *List[T]) UpdateAt(index int, value T) {
|
||||
data := l.data
|
||||
size := len(data)
|
||||
|
||||
if index < 0 || index >= size {
|
||||
return
|
||||
}
|
||||
l.data = append(data[:index], append([]T{value}, data[index+1:]...)...)
|
||||
}
|
||||
|
||||
// Equtal compare list to other list, use reflect.DeepEqual
|
||||
func (l *List[T]) Equtal(other *List[T]) bool {
|
||||
if len(l.data) != len(other.data) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := 0; i < len(l.data); i++ {
|
||||
if !reflect.DeepEqual(l.data[i], other.data[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// IsEmpty check if the list is empty or not
|
||||
func (l *List[T]) IsEmpty() bool {
|
||||
return len(l.data) == 0
|
||||
}
|
||||
|
||||
// Clear the data of list
|
||||
func (l *List[T]) Clear() {
|
||||
l.data = make([]T, 0, 0)
|
||||
}
|
||||
|
||||
// Clone return a copy of list
|
||||
func (l *List[T]) Clone() *List[T] {
|
||||
cl := NewList(make([]T, len(l.data)))
|
||||
copy(cl.data, l.data)
|
||||
|
||||
return cl
|
||||
}
|
||||
|
||||
// Merge two list, return new list, don't change original list
|
||||
func (l *List[T]) Merge(other *List[T]) *List[T] {
|
||||
l1, l2 := len(l.data), len(other.data)
|
||||
ml := NewList(make([]T, l1+l2, l1+l2))
|
||||
|
||||
data := append([]T{}, append(l.data, other.data...)...)
|
||||
ml.data = data
|
||||
|
||||
return ml
|
||||
}
|
||||
|
||||
// Size return number of list data items
|
||||
func (l *List[T]) Size() int {
|
||||
return len(l.data)
|
||||
}
|
||||
|
||||
// Swap the value of index i and j in list
|
||||
func (l *List[T]) Swap(i, j int) {
|
||||
size := len(l.data)
|
||||
if i < 0 || i >= size || j < 0 || j >= size {
|
||||
return
|
||||
}
|
||||
l.data[i], l.data[j] = l.data[j], l.data[i]
|
||||
}
|
||||
|
||||
// Reverse the item order of list
|
||||
func (l *List[T]) Reverse() {
|
||||
for i, j := 0, len(l.data)-1; i < j; i, j = i+1, j-1 {
|
||||
l.data[i], l.data[j] = l.data[j], l.data[i]
|
||||
}
|
||||
}
|
||||
|
||||
// Unique remove duplicate items in list
|
||||
func (l *List[T]) Unique() {
|
||||
data := l.data
|
||||
size := len(data)
|
||||
|
||||
uniqueData := make([]T, 0, 0)
|
||||
for i := 0; i < size; i++ {
|
||||
value := data[i]
|
||||
skip := true
|
||||
for _, v := range uniqueData {
|
||||
if reflect.DeepEqual(value, v) {
|
||||
skip = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if skip {
|
||||
uniqueData = append(uniqueData, value)
|
||||
}
|
||||
}
|
||||
|
||||
l.data = uniqueData
|
||||
}
|
||||
|
||||
// Union creates a new list contain all element in list l and other, remove duplicate element.
|
||||
func (l *List[T]) Union(other *List[T]) *List[T] {
|
||||
res := NewList([]T{})
|
||||
|
||||
res.data = append(res.data, l.data...)
|
||||
res.data = append(res.data, other.data...)
|
||||
res.Unique()
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// Intersection creates a new list whose element both be contained in list l and other
|
||||
func (l *List[T]) Intersection(other *List[T]) *List[T] {
|
||||
res := NewList(make([]T, 0, 0))
|
||||
|
||||
for _, v := range l.data {
|
||||
if other.Contain(v) {
|
||||
res.data = append(res.data, v)
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
272
datastructure/list/list_test.go
Normal file
272
datastructure/list/list_test.go
Normal file
@@ -0,0 +1,272 @@
|
||||
package datastructure
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestListData(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestListData")
|
||||
|
||||
list := NewList([]int{1, 2, 3})
|
||||
assert.Equal([]int{1, 2, 3}, list.Data())
|
||||
}
|
||||
|
||||
func TestValueOf(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestValueOf")
|
||||
|
||||
list := NewList([]int{1, 2, 3})
|
||||
v, ok := list.ValueOf(0)
|
||||
assert.Equal(1, *v)
|
||||
assert.Equal(true, ok)
|
||||
|
||||
_, ok = list.ValueOf(3)
|
||||
assert.Equal(false, ok)
|
||||
}
|
||||
|
||||
func TestIndexOf(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestIndexOf")
|
||||
|
||||
list := NewList([]int{1, 2, 3})
|
||||
i := list.IndexOf(1)
|
||||
assert.Equal(0, i)
|
||||
|
||||
i = list.IndexOf(4)
|
||||
assert.Equal(-1, i)
|
||||
}
|
||||
|
||||
func TestContain(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestContain")
|
||||
|
||||
list := NewList([]int{1, 2, 3})
|
||||
assert.Equal(true, list.Contain(1))
|
||||
assert.Equal(false, list.Contain(0))
|
||||
}
|
||||
|
||||
func TestPush(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestPush")
|
||||
|
||||
list := NewList([]int{1, 2, 3})
|
||||
list.Push(4)
|
||||
|
||||
assert.Equal([]int{1, 2, 3, 4}, list.Data())
|
||||
}
|
||||
|
||||
func TestInsertAtFirst(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestInsertAtFirst")
|
||||
|
||||
list := NewList([]int{1, 2, 3})
|
||||
list.InsertAtFirst(0)
|
||||
|
||||
assert.Equal([]int{0, 1, 2, 3}, list.Data())
|
||||
}
|
||||
|
||||
func TestInsertAtLast(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestInsertAtLast")
|
||||
|
||||
list := NewList([]int{1, 2, 3})
|
||||
list.InsertAtLast(4)
|
||||
|
||||
assert.Equal([]int{1, 2, 3, 4}, list.Data())
|
||||
}
|
||||
|
||||
func TestInsertAt(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestInsertAt")
|
||||
|
||||
list := NewList([]int{1, 2, 3})
|
||||
|
||||
list.InsertAt(-1, 0)
|
||||
assert.Equal([]int{1, 2, 3}, list.Data())
|
||||
|
||||
list.InsertAt(4, 0)
|
||||
assert.Equal([]int{1, 2, 3}, list.Data())
|
||||
|
||||
list.InsertAt(0, 0)
|
||||
assert.Equal([]int{0, 1, 2, 3}, list.Data())
|
||||
|
||||
list.InsertAt(4, 4)
|
||||
assert.Equal([]int{0, 1, 2, 3, 4}, list.Data())
|
||||
}
|
||||
|
||||
func TestPopFirst(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestPopFirst")
|
||||
|
||||
list := NewList([]int{1, 2, 3})
|
||||
v, ok := list.PopFirst()
|
||||
assert.Equal(1, *v)
|
||||
assert.Equal(true, ok)
|
||||
assert.Equal([]int{2, 3}, list.Data())
|
||||
|
||||
list2 := NewList([]int{})
|
||||
_, ok = list2.PopFirst()
|
||||
assert.Equal(false, ok)
|
||||
assert.Equal([]int{}, list2.Data())
|
||||
}
|
||||
|
||||
func TestPopLast(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestPopLast")
|
||||
|
||||
list := NewList([]int{1, 2, 3})
|
||||
v, ok := list.PopLast()
|
||||
assert.Equal(3, *v)
|
||||
assert.Equal(true, ok)
|
||||
assert.Equal([]int{1, 2}, list.Data())
|
||||
|
||||
list2 := NewList([]int{})
|
||||
_, ok = list2.PopLast()
|
||||
assert.Equal(false, ok)
|
||||
assert.Equal([]int{}, list2.Data())
|
||||
}
|
||||
|
||||
func TestDeleteAt(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestDeleteAt")
|
||||
|
||||
list := NewList([]int{1, 2, 3, 4})
|
||||
|
||||
list.DeleteAt(-1)
|
||||
assert.Equal([]int{1, 2, 3, 4}, list.Data())
|
||||
|
||||
list.DeleteAt(4)
|
||||
assert.Equal([]int{1, 2, 3, 4}, list.Data())
|
||||
|
||||
list.DeleteAt(0)
|
||||
assert.Equal([]int{2, 3, 4}, list.Data())
|
||||
|
||||
list.DeleteAt(2)
|
||||
assert.Equal([]int{2, 3}, list.Data())
|
||||
}
|
||||
|
||||
func TestUpdateAt(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestUpdateAt")
|
||||
|
||||
list := NewList([]int{1, 2, 3, 4})
|
||||
|
||||
list.UpdateAt(-1, 0)
|
||||
assert.Equal([]int{1, 2, 3, 4}, list.Data())
|
||||
|
||||
list.UpdateAt(4, 0)
|
||||
assert.Equal([]int{1, 2, 3, 4}, list.Data())
|
||||
|
||||
list.UpdateAt(0, 5)
|
||||
assert.Equal([]int{5, 2, 3, 4}, list.Data())
|
||||
|
||||
list.UpdateAt(3, 1)
|
||||
assert.Equal([]int{5, 2, 3, 1}, list.Data())
|
||||
}
|
||||
|
||||
func TestEqutal(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestEqutal")
|
||||
|
||||
list1 := NewList([]int{1, 2, 3, 4})
|
||||
list2 := NewList([]int{1, 2, 3, 4})
|
||||
list3 := NewList([]int{1, 2, 3})
|
||||
|
||||
assert.Equal(true, list1.Equtal(list2))
|
||||
assert.Equal(false, list1.Equtal(list3))
|
||||
}
|
||||
|
||||
func TestIsEmpty(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestIsEmpty")
|
||||
|
||||
list1 := NewList([]int{1, 2, 3, 4})
|
||||
list2 := NewList([]int{})
|
||||
|
||||
assert.Equal(false, list1.IsEmpty())
|
||||
assert.Equal(true, list2.IsEmpty())
|
||||
}
|
||||
|
||||
func TestIsClear(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestIsClear")
|
||||
|
||||
list1 := NewList([]int{1, 2, 3, 4})
|
||||
list1.Clear()
|
||||
empty := NewList([]int{})
|
||||
|
||||
assert.Equal(empty, list1)
|
||||
}
|
||||
|
||||
func TestClone(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestClone")
|
||||
|
||||
list1 := NewList([]int{1, 2, 3, 4})
|
||||
list2 := list1.Clone()
|
||||
|
||||
assert.Equal(true, list1.Equtal(list2))
|
||||
}
|
||||
|
||||
func TestMerge(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestMerge")
|
||||
|
||||
list1 := NewList([]int{1, 2, 3, 4})
|
||||
list2 := NewList([]int{4, 5, 6})
|
||||
expected := NewList([]int{1, 2, 3, 4, 4, 5, 6})
|
||||
|
||||
list3 := list1.Merge(list2)
|
||||
assert.Equal(true, expected.Equtal(list3))
|
||||
}
|
||||
|
||||
func TestSize(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSize")
|
||||
|
||||
list := NewList([]int{1, 2, 3, 4})
|
||||
empty := NewList([]int{})
|
||||
|
||||
assert.Equal(4, list.Size())
|
||||
assert.Equal(0, empty.Size())
|
||||
}
|
||||
|
||||
func TestSwap(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSwap")
|
||||
|
||||
list := NewList([]int{1, 2, 3, 4})
|
||||
expected := NewList([]int{4, 2, 3, 1})
|
||||
|
||||
list.Swap(0, 3)
|
||||
|
||||
assert.Equal(true, expected.Equtal(list))
|
||||
}
|
||||
|
||||
func TestReverse(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestReverse")
|
||||
|
||||
list := NewList([]int{1, 2, 3, 4})
|
||||
expected := NewList([]int{4, 3, 2, 1})
|
||||
|
||||
list.Reverse()
|
||||
|
||||
assert.Equal(true, expected.Equtal(list))
|
||||
}
|
||||
|
||||
func TestUnique(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestUnique")
|
||||
|
||||
list := NewList([]int{1, 2, 2, 3, 4})
|
||||
expected := NewList([]int{1, 2, 3, 4})
|
||||
|
||||
list.Unique()
|
||||
|
||||
assert.Equal(true, expected.Equtal(list))
|
||||
}
|
||||
|
||||
func TestUnion(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestUnion")
|
||||
|
||||
list1 := NewList([]int{1, 2, 3, 4})
|
||||
list2 := NewList([]int{4, 5, 6})
|
||||
expected := NewList([]int{1, 2, 3, 4, 5, 6})
|
||||
|
||||
list3 := list1.Union(list2)
|
||||
assert.Equal(true, expected.Equtal(list3))
|
||||
}
|
||||
|
||||
func TestIntersection(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestIntersection")
|
||||
|
||||
list1 := NewList([]int{1, 2, 3, 4})
|
||||
list2 := NewList([]int{4, 5, 6})
|
||||
expected := NewList([]int{4})
|
||||
|
||||
list3 := list1.Intersection(list2)
|
||||
assert.Equal(true, expected.Equtal(list3))
|
||||
}
|
||||
51
datastructure/node.go
Normal file
51
datastructure/node.go
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
|
||||
// Use of this source code is governed by MIT license
|
||||
|
||||
// Package datastructure implements some data structure. eg. list, linklist, stack, queue, tree, graph.
|
||||
package datastructure
|
||||
|
||||
// LinkNode is a linkedlist node, which have a Value and Pre points to previous node, Next points to a next node of the link.
|
||||
type LinkNode[T any] struct {
|
||||
Value T
|
||||
Pre *LinkNode[T]
|
||||
Next *LinkNode[T]
|
||||
}
|
||||
|
||||
// NewLinkNode return a LinkNode pointer
|
||||
func NewLinkNode[T any](value T) *LinkNode[T] {
|
||||
return &LinkNode[T]{value, nil, nil}
|
||||
}
|
||||
|
||||
// StackNode is a node in stack, which have a Value and Next pointer points to next node in the stack.
|
||||
type StackNode[T any] struct {
|
||||
Value T
|
||||
Next *StackNode[T]
|
||||
}
|
||||
|
||||
// NewStackNode return a StackNode pointer
|
||||
func NewStackNode[T any](value T) *StackNode[T] {
|
||||
return &StackNode[T]{value, nil}
|
||||
}
|
||||
|
||||
// QueueNode is a node in a queue, which have a Value and Next pointer points to next node in the queue.
|
||||
type QueueNode[T any] struct {
|
||||
Value T
|
||||
Next *QueueNode[T]
|
||||
}
|
||||
|
||||
// NewQueueNode return a QueueNode pointer
|
||||
func NewQueueNode[T any](value T) *QueueNode[T] {
|
||||
return &QueueNode[T]{value, nil}
|
||||
}
|
||||
|
||||
// TreeNode is node of tree
|
||||
type TreeNode[T any] struct {
|
||||
Data T
|
||||
Left *TreeNode[T]
|
||||
Right *TreeNode[T]
|
||||
}
|
||||
|
||||
// NewTreeNode return a TreeNode pointer
|
||||
func NewTreeNode[T any](data T) *TreeNode[T] {
|
||||
return &TreeNode[T]{data, nil, nil}
|
||||
}
|
||||
92
datastructure/queue/arrayqueue.go
Normal file
92
datastructure/queue/arrayqueue.go
Normal file
@@ -0,0 +1,92 @@
|
||||
package datastructure
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// ArrayQueue implements queue with slice
|
||||
type ArrayQueue[T any] struct {
|
||||
data []T
|
||||
length int
|
||||
}
|
||||
|
||||
// NewArrayQueue return a empty ArrayQueue pointer
|
||||
func NewArrayQueue[T any](values ...T) *ArrayQueue[T] {
|
||||
data := make([]T, len(values))
|
||||
for i, v := range values {
|
||||
data[i] = v
|
||||
}
|
||||
return &ArrayQueue[T]{data: data, length: len(values)}
|
||||
}
|
||||
|
||||
// Data return queue data
|
||||
func (q *ArrayQueue[T]) Data() []T {
|
||||
return q.data
|
||||
}
|
||||
|
||||
// Size return length of queue data
|
||||
func (q *ArrayQueue[T]) Size() int {
|
||||
return q.length
|
||||
}
|
||||
|
||||
// IsEmpty checks if queue is empty or not
|
||||
func (q *ArrayQueue[T]) IsEmpty() bool {
|
||||
return q.length == 0
|
||||
}
|
||||
|
||||
// Front return front value of queue
|
||||
func (q *ArrayQueue[T]) Front() T {
|
||||
return q.data[0]
|
||||
}
|
||||
|
||||
// Back return back value of queue
|
||||
func (q *ArrayQueue[T]) Back() T {
|
||||
return q.data[q.length-1]
|
||||
}
|
||||
|
||||
// EnQueue put element into queue
|
||||
func (q *ArrayQueue[T]) EnQueue(value T) {
|
||||
q.data = append(q.data, value)
|
||||
q.length++
|
||||
}
|
||||
|
||||
// DeQueue remove head element of queue and return it, if queue is empty, return nil and error
|
||||
func (q *ArrayQueue[T]) DeQueue() (*T, error) {
|
||||
if q.IsEmpty() {
|
||||
return nil, errors.New("queue is empty")
|
||||
}
|
||||
|
||||
headItem := q.data[0]
|
||||
q.data = q.data[1:]
|
||||
q.length--
|
||||
|
||||
return &headItem, nil
|
||||
}
|
||||
|
||||
// Clear the queue data
|
||||
func (q *ArrayQueue[T]) Clear() {
|
||||
q.data = []T{}
|
||||
q.length = 0
|
||||
}
|
||||
|
||||
// Contain checks if the value is in queue or not
|
||||
func (q *ArrayQueue[T]) Contain(value T) bool {
|
||||
for _, v := range q.data {
|
||||
if reflect.DeepEqual(v, value) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Print queue data
|
||||
func (q *ArrayQueue[T]) Print() {
|
||||
info := "["
|
||||
for _, v := range q.data {
|
||||
info += fmt.Sprintf("%+v, ", v)
|
||||
}
|
||||
info += "]"
|
||||
fmt.Println(info)
|
||||
}
|
||||
90
datastructure/queue/arrayqueue_test.go
Normal file
90
datastructure/queue/arrayqueue_test.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package datastructure
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestArrayQueue_EnQueue(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestArrayQueue_EnQueue")
|
||||
|
||||
queue := NewArrayQueue[int]()
|
||||
queue.EnQueue(1)
|
||||
queue.EnQueue(2)
|
||||
queue.EnQueue(3)
|
||||
|
||||
expected := []int{1, 2, 3}
|
||||
data := queue.Data()
|
||||
size := queue.Size()
|
||||
|
||||
queue.Print()
|
||||
|
||||
assert.Equal(expected, data)
|
||||
assert.Equal(3, size)
|
||||
}
|
||||
|
||||
func TestArrayQueue_DeQueue(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestArrayQueue_DeQueue")
|
||||
|
||||
queue := NewArrayQueue(1, 2, 3)
|
||||
|
||||
val, err := queue.DeQueue()
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
queue.Print()
|
||||
assert.Equal(1, *val)
|
||||
|
||||
assert.Equal([]int{2, 3}, queue.Data())
|
||||
}
|
||||
|
||||
func TestArrayQueue_Front(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestArrayQueue_Front")
|
||||
|
||||
queue := NewArrayQueue(1, 2, 3)
|
||||
val := queue.Front()
|
||||
|
||||
queue.Print()
|
||||
|
||||
assert.Equal(1, val)
|
||||
assert.Equal([]int{1, 2, 3}, queue.Data())
|
||||
}
|
||||
|
||||
func TestArrayQueue_Back(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestArrayQueue_Back")
|
||||
|
||||
queue := NewArrayQueue(1, 2, 3)
|
||||
val := queue.Back()
|
||||
|
||||
queue.Print()
|
||||
|
||||
assert.Equal(3, val)
|
||||
assert.Equal([]int{1, 2, 3}, queue.Data())
|
||||
}
|
||||
|
||||
func TestArrayQueue_Contain(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestArrayQueue_Contain")
|
||||
|
||||
queue := NewArrayQueue(1, 2, 3)
|
||||
|
||||
assert.Equal(true, queue.Contain(1))
|
||||
assert.Equal(false, queue.Contain(4))
|
||||
}
|
||||
|
||||
func TestArrayQueue_Clear(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestArrayQueue_Clear")
|
||||
|
||||
queue := NewArrayQueue[int]()
|
||||
assert.Equal(true, queue.IsEmpty())
|
||||
assert.Equal(0, queue.Size())
|
||||
|
||||
queue.EnQueue(1)
|
||||
assert.Equal(false, queue.IsEmpty())
|
||||
assert.Equal(1, queue.Size())
|
||||
|
||||
queue.Clear()
|
||||
assert.Equal(true, queue.IsEmpty())
|
||||
assert.Equal(0, queue.Size())
|
||||
}
|
||||
118
datastructure/queue/circularqueue.go
Normal file
118
datastructure/queue/circularqueue.go
Normal file
@@ -0,0 +1,118 @@
|
||||
package datastructure
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// CircularQueue implements circular queue with slice,
|
||||
// last index of CircularQueue don't contain value, so acturl capacity is size - 1
|
||||
type CircularQueue[T any] struct {
|
||||
data []T
|
||||
front int
|
||||
rear int
|
||||
size int
|
||||
}
|
||||
|
||||
// NewCircularQueue return a empty CircularQueue pointer
|
||||
func NewCircularQueue[T any](size int) *CircularQueue[T] {
|
||||
data := make([]T, size)
|
||||
return &CircularQueue[T]{data: data, front: 0, rear: 0, size: size}
|
||||
}
|
||||
|
||||
// Data return queue data
|
||||
func (q *CircularQueue[T]) Data() []T {
|
||||
data := []T{}
|
||||
|
||||
front := q.front
|
||||
rear := q.rear
|
||||
if front <= rear {
|
||||
return q.data[front:rear]
|
||||
}
|
||||
|
||||
data = append(data, q.data[front:]...)
|
||||
data = append(data, q.data[0:rear]...)
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
// Length return current data length of queue
|
||||
func (q *CircularQueue[T]) Length() int {
|
||||
if q.size == 0 {
|
||||
return 0
|
||||
}
|
||||
return (q.rear - q.front + q.size) % q.size
|
||||
}
|
||||
|
||||
// IsEmpty checks if queue is empty or not
|
||||
func (q *CircularQueue[T]) IsEmpty() bool {
|
||||
return q.front == q.rear
|
||||
}
|
||||
|
||||
// IsFull checks if queue is full or not
|
||||
func (q *CircularQueue[T]) IsFull() bool {
|
||||
return (q.rear+1)%q.size == q.front
|
||||
}
|
||||
|
||||
// Front return front value of queue
|
||||
func (q *CircularQueue[T]) Front() T {
|
||||
return q.data[q.front]
|
||||
}
|
||||
|
||||
// Back return back value of queue
|
||||
func (q *CircularQueue[T]) Back() T {
|
||||
if q.rear-1 >= 0 {
|
||||
return q.data[q.rear-1]
|
||||
}
|
||||
return q.data[q.size-1]
|
||||
}
|
||||
|
||||
// EnQueue put element into queue
|
||||
func (q *CircularQueue[T]) EnQueue(value T) error {
|
||||
if q.IsFull() {
|
||||
return errors.New("queue is full!")
|
||||
}
|
||||
|
||||
q.data[q.rear] = value
|
||||
q.rear = (q.rear + 1) % q.size
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeQueue remove head element of queue and return it, if queue is empty, return nil and error
|
||||
func (q *CircularQueue[T]) DeQueue() (*T, error) {
|
||||
if q.IsEmpty() {
|
||||
return nil, errors.New("queue is empty")
|
||||
}
|
||||
|
||||
headItem := q.data[q.front]
|
||||
var t T
|
||||
q.data[q.front] = t
|
||||
q.front = (q.front + 1) % q.size
|
||||
|
||||
return &headItem, nil
|
||||
}
|
||||
|
||||
// Clear the queue data
|
||||
func (q *CircularQueue[T]) Clear() {
|
||||
q.data = []T{}
|
||||
q.front = 0
|
||||
q.rear = 0
|
||||
q.size = 0
|
||||
}
|
||||
|
||||
// Contain checks if the value is in queue or not
|
||||
func (q *CircularQueue[T]) Contain(value T) bool {
|
||||
for _, v := range q.data {
|
||||
if reflect.DeepEqual(v, value) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Print queue data
|
||||
func (q *CircularQueue[T]) Print() {
|
||||
fmt.Printf("%+v\n", q)
|
||||
}
|
||||
148
datastructure/queue/circularqueue_test.go
Normal file
148
datastructure/queue/circularqueue_test.go
Normal file
@@ -0,0 +1,148 @@
|
||||
package datastructure
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestCircularQueue_EnQueue(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestCircularQueue_EnQueue")
|
||||
|
||||
queue := NewCircularQueue[int](6)
|
||||
queue.EnQueue(1)
|
||||
queue.EnQueue(2)
|
||||
queue.EnQueue(3)
|
||||
queue.EnQueue(4)
|
||||
queue.EnQueue(5)
|
||||
|
||||
queue.Print()
|
||||
// assert.Equal([]int{1, 2, 3, 4, 5}, queue.Data())
|
||||
assert.Equal(5, queue.Length())
|
||||
|
||||
err := queue.EnQueue(6)
|
||||
assert.IsNotNil(err)
|
||||
}
|
||||
|
||||
func TestCircularQueue_DeQueue(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestCircularQueue_DeQueue")
|
||||
|
||||
queue := NewCircularQueue[int](6)
|
||||
assert.Equal(true, queue.IsEmpty())
|
||||
|
||||
queue.EnQueue(1)
|
||||
queue.EnQueue(2)
|
||||
queue.EnQueue(3)
|
||||
queue.EnQueue(4)
|
||||
queue.EnQueue(5)
|
||||
|
||||
val, err := queue.DeQueue()
|
||||
assert.IsNil(err)
|
||||
|
||||
assert.Equal(1, *val)
|
||||
assert.Equal(false, queue.IsFull())
|
||||
|
||||
val, _ = queue.DeQueue()
|
||||
queue.Print()
|
||||
assert.Equal(2, *val)
|
||||
|
||||
queue.EnQueue(6)
|
||||
queue.Print()
|
||||
assert.Equal(false, queue.IsFull())
|
||||
}
|
||||
|
||||
func TestCircularQueue_Front(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestCircularQueue_Front")
|
||||
|
||||
queue := NewCircularQueue[int](6)
|
||||
queue.EnQueue(1)
|
||||
queue.EnQueue(2)
|
||||
queue.EnQueue(3)
|
||||
queue.EnQueue(4)
|
||||
queue.EnQueue(5)
|
||||
|
||||
queue.Print()
|
||||
|
||||
queue.DeQueue()
|
||||
queue.DeQueue()
|
||||
queue.EnQueue(6)
|
||||
queue.EnQueue(7)
|
||||
|
||||
queue.Print()
|
||||
|
||||
val := queue.Front()
|
||||
assert.Equal(3, val)
|
||||
assert.Equal(5, queue.Length())
|
||||
}
|
||||
|
||||
func TestCircularQueue_Back(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestCircularQueue_Back")
|
||||
|
||||
queue := NewCircularQueue[int](6)
|
||||
assert.Equal(true, queue.IsEmpty())
|
||||
|
||||
queue.EnQueue(1)
|
||||
queue.EnQueue(2)
|
||||
queue.EnQueue(3)
|
||||
queue.EnQueue(4)
|
||||
queue.EnQueue(5)
|
||||
|
||||
queue.Print()
|
||||
assert.Equal(5, queue.Back())
|
||||
|
||||
queue.DeQueue()
|
||||
queue.DeQueue()
|
||||
queue.EnQueue(6)
|
||||
queue.EnQueue(7)
|
||||
|
||||
queue.Print()
|
||||
assert.Equal(7, queue.Back())
|
||||
}
|
||||
|
||||
func TestCircularQueue_Contain(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestCircularQueue_Contain")
|
||||
|
||||
queue := NewCircularQueue[int](2)
|
||||
queue.EnQueue(1)
|
||||
assert.Equal(true, queue.Contain(1))
|
||||
assert.Equal(false, queue.Contain(2))
|
||||
}
|
||||
|
||||
func TestCircularQueue_Clear(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestCircularQueue_Clear")
|
||||
|
||||
queue := NewCircularQueue[int](3)
|
||||
assert.Equal(true, queue.IsEmpty())
|
||||
assert.Equal(0, queue.Length())
|
||||
|
||||
queue.EnQueue(1)
|
||||
assert.Equal(false, queue.IsEmpty())
|
||||
assert.Equal(1, queue.Length())
|
||||
|
||||
queue.Clear()
|
||||
assert.Equal(true, queue.IsEmpty())
|
||||
assert.Equal(0, queue.Length())
|
||||
}
|
||||
|
||||
func TestCircularQueue_Data(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestCircularQueue_Data")
|
||||
|
||||
queue := NewCircularQueue[int](6)
|
||||
queue.EnQueue(1)
|
||||
queue.EnQueue(2)
|
||||
queue.EnQueue(3)
|
||||
queue.EnQueue(4)
|
||||
queue.EnQueue(5)
|
||||
|
||||
queue.Print()
|
||||
assert.Equal([]int{1, 2, 3, 4, 5}, queue.Data())
|
||||
|
||||
queue.DeQueue()
|
||||
queue.DeQueue()
|
||||
queue.EnQueue(6)
|
||||
queue.EnQueue(7)
|
||||
|
||||
queue.Print()
|
||||
assert.Equal([]int{3, 4, 5, 6, 7}, queue.Data())
|
||||
|
||||
}
|
||||
104
datastructure/queue/linkedqueue.go
Normal file
104
datastructure/queue/linkedqueue.go
Normal file
@@ -0,0 +1,104 @@
|
||||
package datastructure
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/duke-git/lancet/v2/datastructure"
|
||||
)
|
||||
|
||||
// LinkedQueue implements queue with link list
|
||||
type LinkedQueue[T any] struct {
|
||||
head *datastructure.QueueNode[T]
|
||||
tail *datastructure.QueueNode[T]
|
||||
length int
|
||||
}
|
||||
|
||||
// NewLinkedQueue return a empty LinkedQueue pointer
|
||||
func NewLinkedQueue[T any]() *LinkedQueue[T] {
|
||||
return &LinkedQueue[T]{head: nil, tail: nil, length: 0}
|
||||
}
|
||||
|
||||
// Data return queue data
|
||||
func (q *LinkedQueue[T]) Data() []T {
|
||||
res := []T{}
|
||||
current := q.head
|
||||
|
||||
for current != nil {
|
||||
res = append(res, current.Value)
|
||||
current = current.Next
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Size return length of queue data
|
||||
func (q *LinkedQueue[T]) Size() int {
|
||||
return q.length
|
||||
}
|
||||
|
||||
// IsEmpty checks if queue is empty or not
|
||||
func (q *LinkedQueue[T]) IsEmpty() bool {
|
||||
return q.length == 0
|
||||
}
|
||||
|
||||
// EnQueue add element into queue
|
||||
func (q *LinkedQueue[T]) EnQueue(value T) {
|
||||
newNode := datastructure.NewQueueNode(value)
|
||||
|
||||
if q.IsEmpty() {
|
||||
q.head = newNode
|
||||
q.tail = newNode
|
||||
} else {
|
||||
q.tail.Next = newNode
|
||||
q.tail = newNode
|
||||
}
|
||||
q.length++
|
||||
}
|
||||
|
||||
// DeQueue delete head element of queue then return it, if queue is empty, return nil and error
|
||||
func (q *LinkedQueue[T]) DeQueue() (*T, error) {
|
||||
if q.IsEmpty() {
|
||||
return nil, errors.New("queue is empty")
|
||||
}
|
||||
|
||||
head := q.head
|
||||
q.head = q.head.Next
|
||||
q.length--
|
||||
|
||||
return &head.Value, nil
|
||||
}
|
||||
|
||||
// Front return front value of queue
|
||||
func (q *LinkedQueue[T]) Front() (*T, error) {
|
||||
if q.IsEmpty() {
|
||||
return nil, errors.New("queue is empty")
|
||||
}
|
||||
return &q.head.Value, nil
|
||||
}
|
||||
|
||||
// Back return back value of queue
|
||||
func (q *LinkedQueue[T]) Back() (*T, error) {
|
||||
if q.IsEmpty() {
|
||||
return nil, errors.New("queue is empty")
|
||||
}
|
||||
return &q.tail.Value, nil
|
||||
}
|
||||
|
||||
// Clear clear the queue data
|
||||
func (q *LinkedQueue[T]) Clear() {
|
||||
q.head = nil
|
||||
q.tail = nil
|
||||
q.length = 0
|
||||
}
|
||||
|
||||
// Print all nodes info of queue link
|
||||
func (q *LinkedQueue[T]) Print() {
|
||||
current := q.head
|
||||
info := "[ "
|
||||
for current != nil {
|
||||
info += fmt.Sprintf("%+v, ", current)
|
||||
current = current.Next
|
||||
}
|
||||
info += " ]"
|
||||
fmt.Println(info)
|
||||
}
|
||||
84
datastructure/queue/linkedqueue_test.go
Normal file
84
datastructure/queue/linkedqueue_test.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package datastructure
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestLinkedQueue_EnQueue(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestLinkedQueue_EnQueue")
|
||||
|
||||
queue := NewLinkedQueue[int]()
|
||||
queue.EnQueue(1)
|
||||
queue.EnQueue(2)
|
||||
queue.EnQueue(3)
|
||||
|
||||
queue.Print()
|
||||
|
||||
assert.Equal([]int{1, 2, 3}, queue.Data())
|
||||
assert.Equal(3, queue.Size())
|
||||
}
|
||||
|
||||
func TestLinkedQueue_DeQueue(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestLinkedQueue_DeQueue")
|
||||
|
||||
queue := NewLinkedQueue[int]()
|
||||
queue.EnQueue(1)
|
||||
queue.EnQueue(2)
|
||||
queue.EnQueue(3)
|
||||
|
||||
val, _ := queue.DeQueue()
|
||||
|
||||
queue.Print()
|
||||
|
||||
assert.Equal([]int{2, 3}, queue.Data())
|
||||
assert.Equal(1, *val)
|
||||
}
|
||||
|
||||
func TestLinkedQueue_Front(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestLinkedQueue_Front")
|
||||
|
||||
queue := NewLinkedQueue[int]()
|
||||
_, err := queue.Front()
|
||||
assert.IsNotNil(err)
|
||||
|
||||
queue.EnQueue(1)
|
||||
queue.EnQueue(2)
|
||||
queue.EnQueue(3)
|
||||
|
||||
val, err := queue.Front()
|
||||
assert.Equal(1, *val)
|
||||
assert.IsNil(err)
|
||||
}
|
||||
|
||||
func TestLinkedQueue_Back(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestLinkedQueue_Back")
|
||||
|
||||
queue := NewLinkedQueue[int]()
|
||||
_, err := queue.Back()
|
||||
assert.IsNotNil(err)
|
||||
|
||||
queue.EnQueue(1)
|
||||
queue.EnQueue(2)
|
||||
queue.EnQueue(3)
|
||||
|
||||
val, err := queue.Back()
|
||||
assert.Equal(3, *val)
|
||||
assert.IsNil(err)
|
||||
}
|
||||
|
||||
func TestLinkedQueue_Clear(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestLinkedQueue_Back")
|
||||
|
||||
queue := NewLinkedQueue[int]()
|
||||
assert.Equal(true, queue.IsEmpty())
|
||||
|
||||
queue.EnQueue(1)
|
||||
queue.EnQueue(2)
|
||||
queue.EnQueue(3)
|
||||
assert.Equal(false, queue.IsEmpty())
|
||||
|
||||
queue.Clear()
|
||||
assert.Equal(true, queue.IsEmpty())
|
||||
}
|
||||
105
datastructure/set/set.go
Normal file
105
datastructure/set/set.go
Normal file
@@ -0,0 +1,105 @@
|
||||
package datastructure
|
||||
|
||||
// Set is a data container, like slice, but element of set is not duplicate
|
||||
type Set[T comparable] map[T]bool
|
||||
|
||||
// NewSet return a instance of set
|
||||
func NewSet[T comparable](values ...T) Set[T] {
|
||||
set := make(Set[T])
|
||||
set.Add(values...)
|
||||
return set
|
||||
}
|
||||
|
||||
// Add value to set
|
||||
func (s Set[T]) Add(values ...T) {
|
||||
for _, v := range values {
|
||||
s[v] = true
|
||||
}
|
||||
}
|
||||
|
||||
// Contain checks if set contains value or not
|
||||
func (s Set[T]) Contain(value T) bool {
|
||||
_, ok := s[value]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Contain checks if set contains other set
|
||||
func (s Set[T]) ContainAll(other Set[T]) bool {
|
||||
for k := range other {
|
||||
_, ok := s[k]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Clone return a copy of set
|
||||
func (s Set[T]) Clone() Set[T] {
|
||||
set := NewSet[T]()
|
||||
set.Add(s.Values()...)
|
||||
return set
|
||||
}
|
||||
|
||||
// Delete value of set
|
||||
func (s Set[T]) Delete(values ...T) {
|
||||
for _, v := range values {
|
||||
delete(s, v)
|
||||
}
|
||||
}
|
||||
|
||||
// Equal checks if two set has same elements or not
|
||||
func (s Set[T]) Equal(other Set[T]) bool {
|
||||
if s.Size() != other.Size() {
|
||||
return false
|
||||
}
|
||||
|
||||
return s.ContainAll(other) && other.ContainAll(s)
|
||||
}
|
||||
|
||||
// Iterate call function by every element of set
|
||||
func (s Set[T]) Iterate(fn func(value T)) {
|
||||
for v := range s {
|
||||
fn(v)
|
||||
}
|
||||
}
|
||||
|
||||
// IsEmpty checks the set is empty or not
|
||||
func (s Set[T]) IsEmpty() bool {
|
||||
return len(s) == 0
|
||||
}
|
||||
|
||||
// Size get the number of elements in set
|
||||
func (s Set[T]) Size() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
// Values return all values of set
|
||||
func (s Set[T]) Values() []T {
|
||||
values := make([]T, 0, 0)
|
||||
|
||||
s.Iterate(func(value T) {
|
||||
values = append(values, value)
|
||||
})
|
||||
|
||||
return values
|
||||
}
|
||||
|
||||
// Union creates a new set contain all element of set s and other
|
||||
func (s Set[T]) Union(other Set[T]) Set[T] {
|
||||
set := s.Clone()
|
||||
set.Add(other.Values()...)
|
||||
return set
|
||||
}
|
||||
|
||||
// Intersection creates a new set whose element both be contained in set s and other
|
||||
func (s Set[T]) Intersection(other Set[T]) Set[T] {
|
||||
set := NewSet[T]()
|
||||
s.Iterate(func(value T) {
|
||||
if other.Contain(value) {
|
||||
set.Add(value)
|
||||
}
|
||||
})
|
||||
|
||||
return set
|
||||
}
|
||||
129
datastructure/set/set_test.go
Normal file
129
datastructure/set/set_test.go
Normal file
@@ -0,0 +1,129 @@
|
||||
package datastructure
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestSet_Add(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSet_Add")
|
||||
|
||||
set := NewSet[int]()
|
||||
set.Add(1, 2, 3)
|
||||
|
||||
expected := NewSet(1, 2, 3)
|
||||
|
||||
assert.Equal(true, set.Equal(expected))
|
||||
}
|
||||
|
||||
func TestSet_Contain(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSet_Contain")
|
||||
|
||||
set := NewSet[int]()
|
||||
set.Add(1, 2, 3)
|
||||
|
||||
assert.Equal(true, set.Contain(1))
|
||||
assert.Equal(false, set.Contain(4))
|
||||
}
|
||||
|
||||
func TestSet_ContainAll(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSet_ContainAll")
|
||||
|
||||
set1 := NewSet(1, 2, 3)
|
||||
set2 := NewSet(1, 2)
|
||||
set3 := NewSet(1, 2, 3, 4)
|
||||
|
||||
assert.Equal(true, set1.ContainAll(set2))
|
||||
assert.Equal(false, set1.ContainAll(set3))
|
||||
}
|
||||
|
||||
func TestSet_Clone(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSet_Clone")
|
||||
|
||||
set1 := NewSet(1, 2, 3)
|
||||
set2 := set1.Clone()
|
||||
|
||||
assert.Equal(true, set1.Size() == set2.Size())
|
||||
assert.Equal(true, set1.ContainAll(set2))
|
||||
}
|
||||
|
||||
func TestSet_Delete(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSet_Delete")
|
||||
|
||||
set := NewSet[int]()
|
||||
set.Add(1, 2, 3)
|
||||
set.Delete(3)
|
||||
|
||||
expected := NewSet(1, 2)
|
||||
|
||||
assert.Equal(true, set.Equal(expected))
|
||||
}
|
||||
|
||||
func TestSet_Equal(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSet_Equal")
|
||||
|
||||
set1 := NewSet(1, 2, 3)
|
||||
set2 := NewSet(1, 2, 3)
|
||||
set3 := NewSet(1, 2, 3, 4)
|
||||
|
||||
assert.Equal(true, set1.Equal(set2))
|
||||
assert.Equal(false, set1.Equal(set3))
|
||||
}
|
||||
|
||||
func TestSet_Iterate(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSet_Iterate")
|
||||
|
||||
set := NewSet(1, 2, 3)
|
||||
arr := []int{}
|
||||
set.Iterate(func(value int) {
|
||||
arr = append(arr, value)
|
||||
})
|
||||
|
||||
assert.Equal(3, len(arr))
|
||||
}
|
||||
|
||||
func TestSet_IsEmpty(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSet_IsEmpty")
|
||||
|
||||
set := NewSet[int]()
|
||||
assert.Equal(true, set.IsEmpty())
|
||||
}
|
||||
|
||||
func TestSet_Size(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSet_Size")
|
||||
|
||||
set := NewSet(1, 2, 3)
|
||||
assert.Equal(3, set.Size())
|
||||
}
|
||||
|
||||
func TestSet_Values(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSet_Values")
|
||||
|
||||
set := NewSet(1, 2, 3)
|
||||
values := set.Values()
|
||||
|
||||
assert.Equal(3, len(values))
|
||||
}
|
||||
|
||||
func TestSet_Union(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSet_Union")
|
||||
|
||||
set1 := NewSet(1, 2, 3)
|
||||
set2 := NewSet(2, 3, 4, 5)
|
||||
expected := NewSet(1, 2, 3, 4, 5)
|
||||
unionSet := set1.Union(set2)
|
||||
|
||||
assert.Equal(expected, unionSet)
|
||||
}
|
||||
|
||||
func TestSet_Intersection(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSet_Intersection")
|
||||
|
||||
set1 := NewSet(1, 2, 3)
|
||||
set2 := NewSet(2, 3, 4, 5)
|
||||
expected := NewSet(2, 3)
|
||||
intersectionSet := set1.Intersection(set2)
|
||||
|
||||
assert.Equal(expected, intersectionSet)
|
||||
}
|
||||
62
datastructure/stack/arraystack.go
Normal file
62
datastructure/stack/arraystack.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package datastructure
|
||||
|
||||
import "errors"
|
||||
|
||||
// ArrayStack implements stack with slice
|
||||
type ArrayStack[T any] struct {
|
||||
data []T
|
||||
length int
|
||||
}
|
||||
|
||||
// NewArrayStack return a empty ArrayStack pointer
|
||||
func NewArrayStack[T any]() *ArrayStack[T] {
|
||||
return &ArrayStack[T]{data: []T{}, length: 0}
|
||||
}
|
||||
|
||||
// Data return stack data
|
||||
func (s *ArrayStack[T]) Data() []T {
|
||||
return s.data
|
||||
}
|
||||
|
||||
// Size return length of stack data
|
||||
func (s *ArrayStack[T]) Size() int {
|
||||
return s.length
|
||||
}
|
||||
|
||||
// IsEmpty checks if stack is empty or not
|
||||
func (s *ArrayStack[T]) IsEmpty() bool {
|
||||
return s.length == 0
|
||||
}
|
||||
|
||||
// Push element into stack
|
||||
func (s *ArrayStack[T]) Push(value T) {
|
||||
s.data = append([]T{value}, s.data...)
|
||||
s.length++
|
||||
}
|
||||
|
||||
// Pop delete the top element of stack then return it, if stack is empty, return nil and error
|
||||
func (s *ArrayStack[T]) Pop() (*T, error) {
|
||||
if s.IsEmpty() {
|
||||
return nil, errors.New("stack is empty")
|
||||
}
|
||||
|
||||
topItem := s.data[0]
|
||||
s.data = s.data[1:]
|
||||
s.length--
|
||||
|
||||
return &topItem, nil
|
||||
}
|
||||
|
||||
// Peak return the top element of stack then return it
|
||||
func (s *ArrayStack[T]) Peak() (*T, error) {
|
||||
if s.IsEmpty() {
|
||||
return nil, errors.New("stack is empty")
|
||||
}
|
||||
return &s.data[0], nil
|
||||
}
|
||||
|
||||
// Clear the stack data
|
||||
func (s *ArrayStack[T]) Clear() {
|
||||
s.data = []T{}
|
||||
s.length = 0
|
||||
}
|
||||
77
datastructure/stack/arraystack_test.go
Normal file
77
datastructure/stack/arraystack_test.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package datastructure
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestArrayStack_Push(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestArrayStack_Push")
|
||||
|
||||
stack := NewArrayStack[int]()
|
||||
stack.Push(1)
|
||||
stack.Push(2)
|
||||
stack.Push(3)
|
||||
|
||||
expected := []int{3, 2, 1}
|
||||
values := stack.Data()
|
||||
length := stack.Size()
|
||||
|
||||
assert.Equal(expected, values)
|
||||
assert.Equal(3, length)
|
||||
}
|
||||
|
||||
func TestArrayStack_Pop(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestArrayStack_Pop")
|
||||
|
||||
stack := NewArrayStack[int]()
|
||||
_, err := stack.Pop()
|
||||
assert.IsNotNil(err)
|
||||
|
||||
stack.Push(1)
|
||||
stack.Push(2)
|
||||
stack.Push(3)
|
||||
|
||||
topItem, err := stack.Pop()
|
||||
assert.IsNil(err)
|
||||
assert.Equal(3, *topItem)
|
||||
|
||||
expected := []int{2, 1}
|
||||
assert.Equal(expected, stack.Data())
|
||||
}
|
||||
|
||||
func TestArrayStack_Peak(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestArrayStack_Peak")
|
||||
|
||||
stack := NewArrayStack[int]()
|
||||
_, err := stack.Peak()
|
||||
assert.IsNotNil(err)
|
||||
|
||||
stack.Push(1)
|
||||
stack.Push(2)
|
||||
stack.Push(3)
|
||||
|
||||
topItem, err := stack.Peak()
|
||||
assert.IsNil(err)
|
||||
assert.Equal(3, *topItem)
|
||||
|
||||
expected := []int{3, 2, 1}
|
||||
assert.Equal(expected, stack.Data())
|
||||
}
|
||||
|
||||
func TestArrayStack_Clear(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestArrayStack_Clear")
|
||||
|
||||
stack := NewArrayStack[int]()
|
||||
assert.Equal(true, stack.IsEmpty())
|
||||
assert.Equal(0, stack.Size())
|
||||
|
||||
stack.Push(1)
|
||||
assert.Equal(false, stack.IsEmpty())
|
||||
assert.Equal(1, stack.Size())
|
||||
|
||||
stack.Clear()
|
||||
assert.Equal(true, stack.IsEmpty())
|
||||
assert.Equal(0, stack.Size())
|
||||
}
|
||||
94
datastructure/stack/linkedstack.go
Normal file
94
datastructure/stack/linkedstack.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package datastructure
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/duke-git/lancet/v2/datastructure"
|
||||
)
|
||||
|
||||
// LinkedStack implements stack with link list
|
||||
type LinkedStack[T any] struct {
|
||||
top *datastructure.StackNode[T]
|
||||
length int
|
||||
}
|
||||
|
||||
// NewLinkedStack return a empty LinkedStack pointer
|
||||
func NewLinkedStack[T any]() *LinkedStack[T] {
|
||||
return &LinkedStack[T]{top: nil, length: 0}
|
||||
}
|
||||
|
||||
// Data return stack data
|
||||
func (s *LinkedStack[T]) Data() []T {
|
||||
res := []T{}
|
||||
current := s.top
|
||||
|
||||
for current != nil {
|
||||
res = append(res, current.Value)
|
||||
current = current.Next
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Size return length of stack data
|
||||
func (s *LinkedStack[T]) Size() int {
|
||||
return s.length
|
||||
}
|
||||
|
||||
// IsEmpty checks if stack is empty or not
|
||||
func (s *LinkedStack[T]) IsEmpty() bool {
|
||||
return s.length == 0
|
||||
}
|
||||
|
||||
// Push element into stack
|
||||
func (s *LinkedStack[T]) Push(value T) {
|
||||
newNode := datastructure.NewStackNode(value)
|
||||
top := s.top
|
||||
if top == nil {
|
||||
s.top = newNode
|
||||
} else {
|
||||
newNode.Next = top
|
||||
s.top = newNode
|
||||
}
|
||||
|
||||
s.length++
|
||||
}
|
||||
|
||||
// Pop delete the top element of stack then return it, if stack is empty, return nil and error
|
||||
func (s *LinkedStack[T]) Pop() (*T, error) {
|
||||
if s.IsEmpty() {
|
||||
return nil, errors.New("stack is empty")
|
||||
}
|
||||
|
||||
top := s.top
|
||||
s.top = s.top.Next
|
||||
s.length--
|
||||
|
||||
return &top.Value, nil
|
||||
}
|
||||
|
||||
// Peak return the top element of stack then return it
|
||||
func (s *LinkedStack[T]) Peak() (*T, error) {
|
||||
if s.IsEmpty() {
|
||||
return nil, errors.New("stack is empty")
|
||||
}
|
||||
return &s.top.Value, nil
|
||||
}
|
||||
|
||||
// Clear clear the stack data
|
||||
func (s *LinkedStack[T]) Clear() {
|
||||
s.top = nil
|
||||
s.length = 0
|
||||
}
|
||||
|
||||
// Print all nodes info of stack link
|
||||
func (s *LinkedStack[T]) Print() {
|
||||
current := s.top
|
||||
info := "[ "
|
||||
for current != nil {
|
||||
info += fmt.Sprintf("%+v, ", current)
|
||||
current = current.Next
|
||||
}
|
||||
info += " ]"
|
||||
fmt.Println(info)
|
||||
}
|
||||
80
datastructure/stack/linkedstack_test.go
Normal file
80
datastructure/stack/linkedstack_test.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package datastructure
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestLinkedStack_Push(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestLinkedStack_Push")
|
||||
|
||||
stack := NewLinkedStack[int]()
|
||||
stack.Push(1)
|
||||
stack.Push(2)
|
||||
stack.Push(3)
|
||||
|
||||
stack.Print()
|
||||
|
||||
expected := []int{3, 2, 1}
|
||||
values := stack.Data()
|
||||
size := stack.Size()
|
||||
|
||||
assert.Equal(expected, values)
|
||||
assert.Equal(3, size)
|
||||
}
|
||||
|
||||
func TestLinkedStack_Pop(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestLinkedStack_Pop")
|
||||
|
||||
stack := NewLinkedStack[int]()
|
||||
_, err := stack.Pop()
|
||||
assert.IsNotNil(err)
|
||||
|
||||
stack.Push(1)
|
||||
stack.Push(2)
|
||||
stack.Push(3)
|
||||
|
||||
topItem, err := stack.Pop()
|
||||
assert.IsNil(err)
|
||||
assert.Equal(3, *topItem)
|
||||
|
||||
expected := []int{2, 1}
|
||||
stack.Print()
|
||||
assert.Equal(expected, stack.Data())
|
||||
}
|
||||
|
||||
func TestLinkedStack_Peak(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestLinkedStack_Peak")
|
||||
|
||||
stack := NewLinkedStack[int]()
|
||||
_, err := stack.Peak()
|
||||
assert.IsNotNil(err)
|
||||
|
||||
stack.Push(1)
|
||||
stack.Push(2)
|
||||
stack.Push(3)
|
||||
|
||||
topItem, err := stack.Peak()
|
||||
assert.IsNil(err)
|
||||
assert.Equal(3, *topItem)
|
||||
|
||||
expected := []int{3, 2, 1}
|
||||
assert.Equal(expected, stack.Data())
|
||||
}
|
||||
|
||||
func TestLinkedStack_Empty(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestLinkedStack_Empty")
|
||||
|
||||
stack := NewLinkedStack[int]()
|
||||
assert.Equal(true, stack.IsEmpty())
|
||||
assert.Equal(0, stack.Size())
|
||||
|
||||
stack.Push(1)
|
||||
assert.Equal(false, stack.IsEmpty())
|
||||
assert.Equal(1, stack.Size())
|
||||
|
||||
stack.Clear()
|
||||
assert.Equal(true, stack.IsEmpty())
|
||||
assert.Equal(0, stack.Size())
|
||||
}
|
||||
83
datastructure/tree/bstree.go
Normal file
83
datastructure/tree/bstree.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package datastructure
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/duke-git/lancet/v2/datastructure"
|
||||
"github.com/duke-git/lancet/v2/lancetconstraints"
|
||||
)
|
||||
|
||||
// BSTree is a binary search tree data structure in which each node has at most two children,
|
||||
// which are referred to as the left child and the right child.
|
||||
// In BSTree: leftNode < rootNode < rightNode
|
||||
// type T should implements Compare function in lancetconstraints.Comparator interface.
|
||||
type BSTree[T any] struct {
|
||||
root *datastructure.TreeNode[T]
|
||||
}
|
||||
|
||||
// NewBSTree create a BSTree pointer
|
||||
func NewBSTree[T any](rootData T) *BSTree[T] {
|
||||
root := datastructure.NewTreeNode(rootData)
|
||||
return &BSTree[T]{root}
|
||||
}
|
||||
|
||||
// InsertNode insert data into BSTree
|
||||
func (t *BSTree[T]) InsertNode(data T, comparator lancetconstraints.Comparator) {
|
||||
root := t.root
|
||||
newNode := datastructure.NewTreeNode(data)
|
||||
if root == nil {
|
||||
t.root = newNode
|
||||
} else {
|
||||
insertTreeNode(root, newNode, comparator)
|
||||
}
|
||||
}
|
||||
|
||||
// DeletetNode delete data into BSTree
|
||||
func (t *BSTree[T]) DeletetNode(data T, comparator lancetconstraints.Comparator) {
|
||||
deleteTreeNode(t.root, data, comparator)
|
||||
}
|
||||
|
||||
// NodeLevel get node level in BSTree
|
||||
func (t *BSTree[T]) NodeLevel(node *datastructure.TreeNode[T]) int {
|
||||
if node == nil {
|
||||
return 0
|
||||
}
|
||||
left := float64(t.NodeLevel(node.Left))
|
||||
right := float64(t.NodeLevel(node.Right))
|
||||
|
||||
return int(math.Max(left, right)) + 1
|
||||
}
|
||||
|
||||
// PreOrderTraverse traverse tree node in pre order
|
||||
func (t *BSTree[T]) PreOrderTraverse() []T {
|
||||
return preOrderTraverse(t.root)
|
||||
}
|
||||
|
||||
// PostOrderTraverse traverse tree node in post order
|
||||
func (t *BSTree[T]) PostOrderTraverse() []T {
|
||||
return postOrderTraverse(t.root)
|
||||
}
|
||||
|
||||
// InOrderTraverse traverse tree node in mid order
|
||||
func (t *BSTree[T]) InOrderTraverse() []T {
|
||||
return inOrderTraverse(t.root)
|
||||
}
|
||||
|
||||
// LevelOrderTraverse traverse tree node in level order
|
||||
func (t *BSTree[T]) LevelOrderTraverse() []T {
|
||||
traversal := make([]T, 0)
|
||||
levelOrderTraverse(t.root, &traversal)
|
||||
return traversal
|
||||
}
|
||||
|
||||
// Depth returns the calculated depth of a binary saerch tree
|
||||
func (t *BSTree[T]) Depth() int {
|
||||
return calculateDepth(t.root, 0)
|
||||
}
|
||||
|
||||
// Print the bstree structure
|
||||
func (t *BSTree[T]) Print() {
|
||||
maxLevel := t.NodeLevel(t.root)
|
||||
nodes := []*datastructure.TreeNode[T]{t.root}
|
||||
printTreeNodes(nodes, 1, maxLevel)
|
||||
}
|
||||
142
datastructure/tree/bstree_test.go
Normal file
142
datastructure/tree/bstree_test.go
Normal file
@@ -0,0 +1,142 @@
|
||||
package datastructure
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func TestBSTree_InsertNode(t *testing.T) {
|
||||
bstree := NewBSTree(6)
|
||||
|
||||
comparator := &intComparator{}
|
||||
bstree.InsertNode(7, comparator)
|
||||
bstree.InsertNode(5, comparator)
|
||||
bstree.InsertNode(2, comparator)
|
||||
bstree.InsertNode(4, comparator)
|
||||
|
||||
bstree.Print()
|
||||
}
|
||||
|
||||
func TestBSTree_PreOrderTraverse(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestBSTree_PreOrderTraverse")
|
||||
|
||||
bstree := NewBSTree(6)
|
||||
|
||||
comparator := &intComparator{}
|
||||
bstree.InsertNode(7, comparator)
|
||||
bstree.InsertNode(5, comparator)
|
||||
bstree.InsertNode(2, comparator)
|
||||
bstree.InsertNode(4, comparator)
|
||||
|
||||
acturl := bstree.PreOrderTraverse()
|
||||
t.Log(acturl)
|
||||
assert.Equal([]int{6, 5, 2, 4, 7}, acturl)
|
||||
}
|
||||
|
||||
func TestBSTree_PostOrderTraverse(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestBSTree_PostOrderTraverse")
|
||||
|
||||
bstree := NewBSTree(6)
|
||||
|
||||
comparator := &intComparator{}
|
||||
bstree.InsertNode(7, comparator)
|
||||
bstree.InsertNode(5, comparator)
|
||||
bstree.InsertNode(2, comparator)
|
||||
bstree.InsertNode(4, comparator)
|
||||
|
||||
acturl := bstree.PostOrderTraverse()
|
||||
t.Log(acturl)
|
||||
assert.Equal([]int{5, 2, 4, 7, 6}, acturl)
|
||||
}
|
||||
|
||||
func TestBSTree_InOrderTraverse(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestBSTree_InOrderTraverse")
|
||||
|
||||
bstree := NewBSTree(6)
|
||||
|
||||
comparator := &intComparator{}
|
||||
bstree.InsertNode(7, comparator)
|
||||
bstree.InsertNode(5, comparator)
|
||||
bstree.InsertNode(2, comparator)
|
||||
bstree.InsertNode(4, comparator)
|
||||
|
||||
acturl := bstree.InOrderTraverse()
|
||||
t.Log(acturl)
|
||||
assert.Equal([]int{2, 4, 5, 6, 7}, acturl)
|
||||
}
|
||||
|
||||
func TestBSTree_LevelOrderTraverse(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestBSTree_LevelOrderTraverse")
|
||||
|
||||
bstree := NewBSTree(6)
|
||||
|
||||
comparator := &intComparator{}
|
||||
bstree.InsertNode(7, comparator)
|
||||
bstree.InsertNode(5, comparator)
|
||||
bstree.InsertNode(2, comparator)
|
||||
bstree.InsertNode(4, comparator)
|
||||
|
||||
bstree.Print()
|
||||
|
||||
acturl := bstree.LevelOrderTraverse()
|
||||
t.Log(acturl)
|
||||
assert.Equal([]int{6, 5, 7, 2, 4}, acturl)
|
||||
}
|
||||
|
||||
func TestBSTree_DeletetNode(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestBSTree_DeletetNode")
|
||||
|
||||
bstree := NewBSTree(6)
|
||||
|
||||
comparator := &intComparator{}
|
||||
bstree.InsertNode(7, comparator)
|
||||
bstree.InsertNode(5, comparator)
|
||||
bstree.InsertNode(2, comparator)
|
||||
bstree.InsertNode(4, comparator)
|
||||
|
||||
bstree.Print()
|
||||
|
||||
bstree.DeletetNode(4, comparator)
|
||||
bstree.Print()
|
||||
acturl1 := bstree.InOrderTraverse()
|
||||
t.Log(acturl1)
|
||||
assert.Equal([]int{2, 5, 6, 7}, acturl1)
|
||||
|
||||
//todo
|
||||
// bstree.DeletetNode(6, comparator)
|
||||
// bstree.Print()
|
||||
// acturl2 := bstree.InOrderTraverse()
|
||||
// t.Log(acturl2)
|
||||
// assert.Equal([]int{2, 5, 7}, acturl2)
|
||||
}
|
||||
|
||||
func TestBSTree_Depth(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestBSTree_Depth")
|
||||
|
||||
bstree := NewBSTree(6)
|
||||
|
||||
comparator := &intComparator{}
|
||||
bstree.InsertNode(7, comparator)
|
||||
bstree.InsertNode(5, comparator)
|
||||
bstree.InsertNode(2, comparator)
|
||||
bstree.InsertNode(4, comparator)
|
||||
|
||||
bstree.Print()
|
||||
|
||||
assert.Equal(bstree.Depth(), 4)
|
||||
}
|
||||
224
datastructure/tree/tree_internal.go
Normal file
224
datastructure/tree/tree_internal.go
Normal file
@@ -0,0 +1,224 @@
|
||||
package datastructure
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"github.com/duke-git/lancet/v2/datastructure"
|
||||
"github.com/duke-git/lancet/v2/lancetconstraints"
|
||||
)
|
||||
|
||||
func preOrderTraverse[T any](node *datastructure.TreeNode[T]) []T {
|
||||
data := []T{}
|
||||
if node != nil {
|
||||
data = append(data, node.Data)
|
||||
data = append(data, preOrderTraverse(node.Left)...)
|
||||
data = append(data, preOrderTraverse(node.Right)...)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func postOrderTraverse[T any](node *datastructure.TreeNode[T]) []T {
|
||||
data := []T{}
|
||||
if node != nil {
|
||||
data = append(data, preOrderTraverse(node.Left)...)
|
||||
data = append(data, preOrderTraverse(node.Right)...)
|
||||
data = append(data, node.Data)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func inOrderTraverse[T any](node *datastructure.TreeNode[T]) []T {
|
||||
data := []T{}
|
||||
if node != nil {
|
||||
data = append(data, inOrderTraverse(node.Left)...)
|
||||
data = append(data, node.Data)
|
||||
data = append(data, inOrderTraverse(node.Right)...)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func preOrderPrint[T any](node *datastructure.TreeNode[T]) {
|
||||
if node == nil {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%v, ", node.Data)
|
||||
preOrderPrint(node.Left)
|
||||
preOrderPrint(node.Right)
|
||||
}
|
||||
|
||||
func postOrderPrint[T any](node *datastructure.TreeNode[T]) {
|
||||
if node == nil {
|
||||
return
|
||||
}
|
||||
|
||||
preOrderPrint(node.Left)
|
||||
preOrderPrint(node.Right)
|
||||
fmt.Printf("%v, ", node.Data)
|
||||
}
|
||||
|
||||
func inOrderPrint[T any](node *datastructure.TreeNode[T]) {
|
||||
if node == nil {
|
||||
return
|
||||
}
|
||||
|
||||
inOrderPrint(node.Left)
|
||||
fmt.Printf("%v, ", node.Data)
|
||||
inOrderPrint(node.Right)
|
||||
}
|
||||
|
||||
func levelOrderTraverse[T any](root *datastructure.TreeNode[T], traversal *[]T) {
|
||||
var q []*datastructure.TreeNode[T] // queue
|
||||
var n *datastructure.TreeNode[T] // temp node
|
||||
|
||||
q = append(q, root)
|
||||
|
||||
for len(q) != 0 {
|
||||
n, q = q[0], q[1:]
|
||||
*traversal = append(*traversal, n.Data)
|
||||
if n.Left != nil {
|
||||
q = append(q, n.Left)
|
||||
}
|
||||
if n.Right != nil {
|
||||
q = append(q, n.Right)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func insertTreeNode[T any](rootNode, newNode *datastructure.TreeNode[T], comparator lancetconstraints.Comparator) {
|
||||
if comparator.Compare(newNode.Data, rootNode.Data) == -1 {
|
||||
if rootNode.Left == nil {
|
||||
rootNode.Left = newNode
|
||||
} else {
|
||||
insertTreeNode(rootNode.Left, newNode, comparator)
|
||||
}
|
||||
} else {
|
||||
if rootNode.Right == nil {
|
||||
rootNode.Right = newNode
|
||||
} else {
|
||||
insertTreeNode(rootNode.Right, newNode, comparator)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// todo, delete root node failed
|
||||
func deleteTreeNode[T any](node *datastructure.TreeNode[T], data T, comparator lancetconstraints.Comparator) *datastructure.TreeNode[T] {
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
if comparator.Compare(data, node.Data) == -1 {
|
||||
node.Left = deleteTreeNode(node.Left, data, comparator)
|
||||
} else if comparator.Compare(data, node.Data) == 1 {
|
||||
node.Right = deleteTreeNode(node.Right, data, comparator)
|
||||
} else {
|
||||
if node.Left == nil {
|
||||
node = node.Right
|
||||
} else if node.Right == nil {
|
||||
node = node.Left
|
||||
} else {
|
||||
l := node.Right
|
||||
d := inOrderSuccessor(l)
|
||||
d.Left = node.Left
|
||||
return node.Right
|
||||
}
|
||||
}
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
func inOrderSuccessor[T any](root *datastructure.TreeNode[T]) *datastructure.TreeNode[T] {
|
||||
cur := root
|
||||
for cur.Left != nil {
|
||||
cur = cur.Left
|
||||
}
|
||||
return cur
|
||||
}
|
||||
|
||||
func printTreeNodes[T any](nodes []*datastructure.TreeNode[T], level, maxLevel int) {
|
||||
if len(nodes) == 0 || isAllNil(nodes) {
|
||||
return
|
||||
}
|
||||
|
||||
floor := maxLevel - level
|
||||
endgeLines := int(math.Pow(float64(2), (math.Max(float64(floor)-1, 0))))
|
||||
firstSpaces := int(math.Pow(float64(2), float64(floor))) - 1
|
||||
betweenSpaces := int(math.Pow(float64(2), float64(floor)+1)) - 1
|
||||
|
||||
printSpaces(firstSpaces)
|
||||
|
||||
newNodes := []*datastructure.TreeNode[T]{}
|
||||
for _, node := range nodes {
|
||||
if node != nil {
|
||||
fmt.Printf("%v", node.Data)
|
||||
newNodes = append(newNodes, node.Left)
|
||||
newNodes = append(newNodes, node.Right)
|
||||
} else {
|
||||
newNodes = append(newNodes, nil)
|
||||
newNodes = append(newNodes, nil)
|
||||
printSpaces(1)
|
||||
}
|
||||
|
||||
printSpaces(betweenSpaces)
|
||||
}
|
||||
|
||||
fmt.Println("")
|
||||
|
||||
for i := 1; i <= endgeLines; i++ {
|
||||
for j := 0; j < len(nodes); j++ {
|
||||
printSpaces(firstSpaces - i)
|
||||
if nodes[j] == nil {
|
||||
printSpaces(endgeLines + endgeLines + i + 1)
|
||||
continue
|
||||
}
|
||||
|
||||
if nodes[j].Left != nil {
|
||||
fmt.Print("/")
|
||||
} else {
|
||||
printSpaces(1)
|
||||
}
|
||||
|
||||
printSpaces(i + i - 1)
|
||||
|
||||
if nodes[j].Right != nil {
|
||||
fmt.Print("\\")
|
||||
} else {
|
||||
printSpaces(1)
|
||||
}
|
||||
printSpaces(endgeLines + endgeLines - 1)
|
||||
}
|
||||
fmt.Println("")
|
||||
}
|
||||
|
||||
printTreeNodes(newNodes, level+1, maxLevel)
|
||||
}
|
||||
|
||||
// printSpaces
|
||||
func printSpaces(n int) {
|
||||
for i := 0; i < n; i++ {
|
||||
fmt.Print(" ")
|
||||
}
|
||||
}
|
||||
|
||||
func isAllNil[T any](nodes []*datastructure.TreeNode[T]) bool {
|
||||
for _, v := range nodes {
|
||||
if v != nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func calculateDepth[T any](node *datastructure.TreeNode[T], depth int) int {
|
||||
if node == nil {
|
||||
return depth
|
||||
}
|
||||
return max(calculateDepth(node.Left, depth+1), calculateDepth(node.Right, depth+1))
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
60
datetime/conversion.go
Normal file
60
datetime/conversion.go
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
|
||||
// Use of this source code is governed by MIT license.
|
||||
|
||||
package datetime
|
||||
|
||||
import "time"
|
||||
|
||||
type theTime struct {
|
||||
unix int64
|
||||
}
|
||||
|
||||
// NewUnixNow return unix timestamp of current time
|
||||
func NewUnixNow() *theTime {
|
||||
return &theTime{unix: time.Now().Unix()}
|
||||
}
|
||||
|
||||
// NewUnix return unix timestamp of specified time
|
||||
func NewUnix(unix int64) *theTime {
|
||||
return &theTime{unix: unix}
|
||||
}
|
||||
|
||||
// NewFormat return unix timestamp of specified time string, t should be "yyyy-mm-dd hh:mm:ss"
|
||||
func NewFormat(t string) (*theTime, error) {
|
||||
timeLayout := "2006-01-02 15:04:05"
|
||||
loc := time.FixedZone("CST", 8*3600)
|
||||
tt, err := time.ParseInLocation(timeLayout, t, loc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &theTime{unix: tt.Unix()}, nil
|
||||
}
|
||||
|
||||
// NewISO8601 return unix timestamp of specified iso8601 time string
|
||||
func NewISO8601(iso8601 string) (*theTime, error) {
|
||||
t, err := time.ParseInLocation(time.RFC3339, iso8601, time.UTC)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &theTime{unix: t.Unix()}, nil
|
||||
}
|
||||
|
||||
// ToUnix return unix timestamp
|
||||
func (t *theTime) ToUnix() int64 {
|
||||
return t.unix
|
||||
}
|
||||
|
||||
// ToFormat return the time string 'yyyy-mm-dd hh:mm:ss' of unix time
|
||||
func (t *theTime) ToFormat() string {
|
||||
return time.Unix(t.unix, 0).Format("2006-01-02 15:04:05")
|
||||
}
|
||||
|
||||
// ToFormatForTpl return the time string which format is specified tpl
|
||||
func (t *theTime) ToFormatForTpl(tpl string) string {
|
||||
return time.Unix(t.unix, 0).Format(tpl)
|
||||
}
|
||||
|
||||
// ToFormatForTpl return iso8601 time string
|
||||
func (t *theTime) ToIso8601() string {
|
||||
return time.Unix(t.unix, 0).Format(time.RFC3339)
|
||||
}
|
||||
53
datetime/conversion_test.go
Normal file
53
datetime/conversion_test.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package datetime
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestToUnix(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestToUnix")
|
||||
|
||||
tm1 := NewUnixNow()
|
||||
unixTimestamp := tm1.ToUnix()
|
||||
tm2 := NewUnix(unixTimestamp)
|
||||
|
||||
assert.Equal(tm1, tm2)
|
||||
}
|
||||
|
||||
func TestToFormat(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestToFormat")
|
||||
|
||||
_, err := NewFormat("2022/03/18 17:04:05")
|
||||
assert.IsNotNil(err)
|
||||
|
||||
tm, err := NewFormat("2022-03-18 17:04:05")
|
||||
assert.IsNil(err)
|
||||
|
||||
t.Log("ToFormat -> ", tm.ToFormat())
|
||||
}
|
||||
|
||||
func TestToFormatForTpl(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestToFormatForTpl")
|
||||
|
||||
_, err := NewFormat("2022/03/18 17:04:05")
|
||||
assert.IsNotNil(err)
|
||||
|
||||
tm, err := NewFormat("2022-03-18 17:04:05")
|
||||
assert.IsNil(err)
|
||||
|
||||
t.Log("ToFormatForTpl -> ", tm.ToFormatForTpl("2006/01/02 15:04:05"))
|
||||
}
|
||||
|
||||
func TestToIso8601(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestToIso8601")
|
||||
|
||||
_, err := NewISO8601("2022-03-18 17:04:05")
|
||||
assert.IsNotNil(err)
|
||||
|
||||
tm, err := NewISO8601("2006-01-02T15:04:05.999Z")
|
||||
assert.IsNil(err)
|
||||
|
||||
t.Log("ToIso8601 -> ", tm.ToIso8601())
|
||||
}
|
||||
@@ -110,3 +110,73 @@ func FormatStrToTime(str, format string) (time.Time, error) {
|
||||
|
||||
return time.Parse(v, str)
|
||||
}
|
||||
|
||||
// BeginOfMinute return beginning minute time of day
|
||||
func BeginOfMinute(t time.Time) time.Time {
|
||||
y, m, d := t.Date()
|
||||
return time.Date(y, m, d, t.Hour(), t.Minute(), 0, 0, t.Location())
|
||||
}
|
||||
|
||||
// EndOfMinute return end minute time of day
|
||||
func EndOfMinute(t time.Time) time.Time {
|
||||
y, m, d := t.Date()
|
||||
return time.Date(y, m, d, t.Hour(), t.Minute(), 59, int(time.Second-time.Nanosecond), t.Location())
|
||||
}
|
||||
|
||||
// BeginOfHour return beginning hour time of day
|
||||
func BeginOfHour(t time.Time) time.Time {
|
||||
y, m, d := t.Date()
|
||||
return time.Date(y, m, d, t.Hour(), 0, 0, 0, t.Location())
|
||||
}
|
||||
|
||||
// EndOfHour return end hour time of day
|
||||
func EndOfHour(t time.Time) time.Time {
|
||||
y, m, d := t.Date()
|
||||
return time.Date(y, m, d, t.Hour(), 59, 59, int(time.Second-time.Nanosecond), t.Location())
|
||||
}
|
||||
|
||||
// BeginOfDay return beginning hour time of day
|
||||
func BeginOfDay(t time.Time) time.Time {
|
||||
y, m, d := t.Date()
|
||||
return time.Date(y, m, d, 0, 0, 0, 0, t.Location())
|
||||
}
|
||||
|
||||
// EndOfDay return end time of day
|
||||
func EndOfDay(t time.Time) time.Time {
|
||||
y, m, d := t.Date()
|
||||
return time.Date(y, m, d, 23, 59, 59, int(time.Second-time.Nanosecond), t.Location())
|
||||
}
|
||||
|
||||
// BeginOfWeek return beginning week, week begin from Sunday
|
||||
func BeginOfWeek(t time.Time) time.Time {
|
||||
y, m, d := t.AddDate(0, 0, 0-int(BeginOfDay(t).Weekday())).Date()
|
||||
return time.Date(y, m, d, 0, 0, 0, 0, t.Location())
|
||||
}
|
||||
|
||||
// EndOfWeek return end week time, week end with Saturday
|
||||
func EndOfWeek(t time.Time) time.Time {
|
||||
y, m, d := BeginOfWeek(t).AddDate(0, 0, 7).Add(-time.Nanosecond).Date()
|
||||
return time.Date(y, m, d, 23, 59, 59, int(time.Second-time.Nanosecond), t.Location())
|
||||
}
|
||||
|
||||
// BeginOfMonth return beginning of month
|
||||
func BeginOfMonth(t time.Time) time.Time {
|
||||
y, m, _ := t.Date()
|
||||
return time.Date(y, m, 1, 0, 0, 0, 0, t.Location())
|
||||
}
|
||||
|
||||
// EndOfMonth return end of month
|
||||
func EndOfMonth(t time.Time) time.Time {
|
||||
return BeginOfMonth(t).AddDate(0, 1, 0).Add(-time.Nanosecond)
|
||||
}
|
||||
|
||||
// BeginOfYear return beginning of year
|
||||
func BeginOfYear(t time.Time) time.Time {
|
||||
y, _, _ := t.Date()
|
||||
return time.Date(y, time.January, 1, 0, 0, 0, 0, t.Location())
|
||||
}
|
||||
|
||||
// EndOfYear return end of year
|
||||
func EndOfYear(t time.Time) time.Time {
|
||||
return BeginOfYear(t).AddDate(1, 0, 0).Add(-time.Nanosecond)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/duke-git/lancet/internal"
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestAddDay(t *testing.T) {
|
||||
@@ -64,16 +64,6 @@ func TestGetNowDateTime(t *testing.T) {
|
||||
assert.Equal(expected, GetNowDateTime())
|
||||
}
|
||||
|
||||
//todo
|
||||
//func TestGetZeroHourTimestamp(t *testing.T) {
|
||||
// ts := GetZeroHourTimestamp()
|
||||
// expected := time.Now().UTC().Unix() - 8*3600
|
||||
// if ts != expected {
|
||||
// utils.LogFailedTestInfo(t, "GetZeroHourTimestamp", "", expected, ts)
|
||||
// t.FailNow()
|
||||
// }
|
||||
//}
|
||||
|
||||
func TestFormatTimeToStr(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestFormatTimeToStr")
|
||||
|
||||
@@ -121,3 +111,123 @@ func TestFormatStrToTime(t *testing.T) {
|
||||
assert.Equal(expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBeginOfMinute(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestBeginOfMinute")
|
||||
|
||||
expected := time.Date(2022, 2, 15, 15, 48, 0, 0, time.Local)
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
actual := BeginOfMinute(td)
|
||||
|
||||
assert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestEndOfMinute(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestEndOfMinute")
|
||||
|
||||
expected := time.Date(2022, 2, 15, 15, 48, 59, 999999999, time.Local)
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
actual := EndOfMinute(td)
|
||||
|
||||
assert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestBeginOfHour(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestBeginOfHour")
|
||||
|
||||
expected := time.Date(2022, 2, 15, 15, 0, 0, 0, time.Local)
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
actual := BeginOfHour(td)
|
||||
|
||||
assert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestEndOfHour(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestEndOfHour")
|
||||
|
||||
expected := time.Date(2022, 2, 15, 15, 59, 59, 999999999, time.Local)
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
actual := EndOfHour(td)
|
||||
|
||||
assert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestBeginOfDay(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestBeginOfDay")
|
||||
|
||||
expected := time.Date(2022, 2, 15, 0, 0, 0, 0, time.Local)
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
actual := BeginOfDay(td)
|
||||
|
||||
assert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestEndOfDay(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestEndOfDay")
|
||||
|
||||
expected := time.Date(2022, 2, 15, 23, 59, 59, 999999999, time.Local)
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
actual := EndOfDay(td)
|
||||
|
||||
assert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestBeginOfWeek(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestBeginOfWeek")
|
||||
|
||||
expected := time.Date(2022, 2, 13, 0, 0, 0, 0, time.Local)
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
actual := BeginOfWeek(td)
|
||||
|
||||
assert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestEndOfWeek(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestEndOfWeek")
|
||||
|
||||
expected := time.Date(2022, 2, 19, 23, 59, 59, 999999999, time.Local)
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
actual := EndOfWeek(td)
|
||||
|
||||
assert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestBeginOfMonth(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestBeginOfMonth")
|
||||
|
||||
expected := time.Date(2022, 2, 1, 0, 0, 0, 0, time.Local)
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
actual := BeginOfMonth(td)
|
||||
|
||||
assert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestEndOfMonth(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestEndOfMonth")
|
||||
|
||||
expected := time.Date(2022, 2, 28, 23, 59, 59, 999999999, time.Local)
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
actual := EndOfMonth(td)
|
||||
|
||||
assert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestBeginOfYear(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestBeginOfYear")
|
||||
|
||||
expected := time.Date(2022, 1, 1, 0, 0, 0, 0, time.Local)
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
actual := BeginOfYear(td)
|
||||
|
||||
assert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestEndOfYear(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestEndOfYear")
|
||||
|
||||
expected := time.Date(2022, 12, 31, 23, 59, 59, 999999999, time.Local)
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
actual := EndOfYear(td)
|
||||
|
||||
assert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
593
docs/algorithm.md
Normal file
593
docs/algorithm.md
Normal file
@@ -0,0 +1,593 @@
|
||||
# Algorithm
|
||||
Package algorithm implements some basic algorithm. eg. sort, search.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/sorter.go](https://github.com/duke-git/lancet/blob/main/algorithm/sorter.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/search.go](https://github.com/duke-git/lancet/blob/main/algorithm/search.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go](https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Usage
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [BubbleSort](#BubbleSort)
|
||||
- [CountSort](#CountSort)
|
||||
- [HeapSort](#HeapSort)
|
||||
- [InsertionSort](#InsertionSort)
|
||||
- [MergeSort](#MergeSort)
|
||||
- [QuickSort](#QuickSort)
|
||||
- [SelectionSort](#SelectionSort)
|
||||
- [ShellSort](#ShellSort)
|
||||
- [BinarySearch](#BinarySearch)
|
||||
- [BinaryIterativeSearch](#BinaryIterativeSearch)
|
||||
- [LinearSearch](#LinearSearch)
|
||||
- [LRUCache](#LRUCache)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
|
||||
### <span id="BubbleSort">BubbleSort</span>
|
||||
<p>Sort slice with bubble sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func BubbleSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
sortedSlice := algorithm.BubbleSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="InsertionSort">InsertionSort</span>
|
||||
<p>Sort slice with insertion sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func InsertionSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type people struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
// PeopleAageComparator sort people slice by age field
|
||||
type peopleAgeComparator struct{}
|
||||
|
||||
// Compare implements github.com/duke-git/lancet/lancetconstraints/constraints.go/Comparator
|
||||
func (pc *peopleAgeComparator) Compare(v1 any, v2 any) int {
|
||||
p1, _ := v1.(people)
|
||||
p2, _ := v2.(people)
|
||||
|
||||
//ascending order
|
||||
if p1.Age < p2.Age {
|
||||
return -1
|
||||
} else if p1.Age > p2.Age {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
|
||||
//decending order
|
||||
// if p1.Age > p2.Age {
|
||||
// return -1
|
||||
// } else if p1.Age < p2.Age {
|
||||
// return 1
|
||||
// }
|
||||
}
|
||||
|
||||
var peoples = []people{
|
||||
{Name: "a", Age: 20},
|
||||
{Name: "b", Age: 10},
|
||||
{Name: "c", Age: 17},
|
||||
{Name: "d", Age: 8},
|
||||
{Name: "e", Age: 28},
|
||||
}
|
||||
comparator := &peopleAgeComparator{}
|
||||
sortedPeople := algorithm.InsertionSort(peoples, comparator)
|
||||
|
||||
fmt.Println(sortedSlice) //[{d 8} {b 10} {c 17} {a 20} {e 28}]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="SelectionSort">SelectionSort</span>
|
||||
<p>Sort slice with selection sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func SelectionSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
sortedSlice := algorithm.SelectionSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="ShellSort">ShellSort</span>
|
||||
<p>Sort slice with shell sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ShellSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
sortedSlice := algorithm.ShellSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="QuickSort">QuickSort</span>
|
||||
<p>Sort slice with quick sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func QuickSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) []T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
sortedSlice := algorithm.QuickSort(intSlice, 0, len(intSlice)-1, comparator)
|
||||
|
||||
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="HeapSort">HeapSort</span>
|
||||
<p>Sort slice with heap sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func HeapSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
sortedSlice := algorithm.HeapSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="MergeSort">MergeSort</span>
|
||||
<p>Sort slice with merge sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func MergeSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) []T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
sortedSlice := algorithm.MergeSort(intSlice, 0, len(intSlice)-1, comparator)
|
||||
|
||||
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="CountSort">CountSort</span>
|
||||
<p>Sort slice with count sort algorithm. Param comparator should implements lancetconstraints.Comparator.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func CountSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
sortedSlice := algorithm.CountSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="BinarySearch">BinarySearch</span>
|
||||
<p>BinarySearch search for target within a sorted slice, recursive call itself. If a target is found, the index of the target is returned. Else the function return -1.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func BinarySearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var sortedNumbers = []int{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
comparator := &intComparator{}
|
||||
foundIndex := algorithm.BinarySearch(sortedNumbers, 5, 0, len(sortedNumbers)-1, comparator)
|
||||
fmt.Println(foundIndex) //4
|
||||
|
||||
notFoundIndex := algorithm.BinarySearch(sortedNumbers, 9, 0, len(sortedNumbers)-1, comparator)
|
||||
fmt.Println(notFoundIndex) //-1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="BinaryIterativeSearch">BinaryIterativeSearch</span>
|
||||
<p>BinaryIterativeSearch search for target within a sorted slice, recursive call itself. If a target is found, the index of the target is returned. Else the function return -1.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func BinaryIterativeSearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var sortedNumbers = []int{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
comparator := &intComparator{}
|
||||
foundIndex := algorithm.BinaryIterativeSearch(sortedNumbers, 5, 0, len(sortedNumbers)-1, comparator)
|
||||
fmt.Println(foundIndex) //4
|
||||
|
||||
notFoundIndex := algorithm.BinaryIterativeSearch(sortedNumbers, 9, 0, len(sortedNumbers)-1, comparator)
|
||||
fmt.Println(notFoundIndex) //-1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="LinearSearch">LinearSearch</span>
|
||||
<p>LinearSearch Simple linear search algorithm that iterates over all elements of an slice. If a target is found, the index of the target is returned. Else the function return -1.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func LinearSearch[T any](slice []T, target T, comparator lancetconstraints.Comparator) int
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
foundIndex := algorithm.LinearSearch(intSlice, 5, comparator)
|
||||
fmt.Println(foundIndex) //2
|
||||
|
||||
notFoundIndex := algorithm.LinearSearch(sortedNumbers, 0, comparator)
|
||||
fmt.Println(notFoundIndex) //-1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="LRUCache">LRUCache</span>
|
||||
<p>LRUCache implements mem cache with lru.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func NewLRUCache[K comparable, V any](capacity int) *LRUCache[K, V]
|
||||
func (l *LRUCache[K, V]) Get(key K) (V, bool)
|
||||
func (l *LRUCache[K, V]) Put(key K, value V)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cache := algorithm.NewLRUCache[int, int](2)
|
||||
|
||||
cache.Put(1, 1)
|
||||
cache.Put(2, 2)
|
||||
|
||||
_, ok := cache.Get(0) // ok -> false
|
||||
|
||||
v, ok := cache.Get(1) // v->1, ok->true
|
||||
|
||||
}
|
||||
```
|
||||
593
docs/algorithm_zh-CN.md
Normal file
593
docs/algorithm_zh-CN.md
Normal file
@@ -0,0 +1,593 @@
|
||||
# Algorithm
|
||||
algorithm算法包实现一些基本算法,sort,search,lrucache。
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 源码
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/sorter.go](https://github.com/duke-git/lancet/blob/main/algorithm/sorter.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/search.go](https://github.com/duke-git/lancet/blob/main/algorithm/search.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go](https://github.com/duke-git/lancet/blob/main/algorithm/lru_cache.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录
|
||||
- [BubbleSort](#BubbleSort)
|
||||
- [CountSort](#CountSort)
|
||||
- [HeapSort](#HeapSort)
|
||||
- [InsertionSort](#InsertionSort)
|
||||
- [MergeSort](#MergeSort)
|
||||
- [QuickSort](#QuickSort)
|
||||
- [SelectionSort](#SelectionSort)
|
||||
- [ShellSort](#ShellSort)
|
||||
- [BinarySearch](#BinarySearch)
|
||||
- [BinaryIterativeSearch](#BinaryIterativeSearch)
|
||||
- [LinearSearch](#LinearSearch)
|
||||
- [LRUCache](#LRUCache)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 文档
|
||||
|
||||
|
||||
|
||||
### <span id="BubbleSort">BubbleSort</span>
|
||||
<p>冒泡排序,参数comparator需要实现包lancetconstraints.Comparator</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func BubbleSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
sortedSlice := algorithm.BubbleSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="InsertionSort">InsertionSort</span>
|
||||
<p>插入排序,参数comparator需要实现包lancetconstraints.Comparator</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func InsertionSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type people struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
// PeopleAageComparator sort people slice by age field
|
||||
type peopleAgeComparator struct{}
|
||||
|
||||
// Compare implements github.com/duke-git/lancet/lancetconstraints/constraints.go/Comparator
|
||||
func (pc *peopleAgeComparator) Compare(v1 any, v2 any) int {
|
||||
p1, _ := v1.(people)
|
||||
p2, _ := v2.(people)
|
||||
|
||||
//ascending order
|
||||
if p1.Age < p2.Age {
|
||||
return -1
|
||||
} else if p1.Age > p2.Age {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
|
||||
//decending order
|
||||
// if p1.Age > p2.Age {
|
||||
// return -1
|
||||
// } else if p1.Age < p2.Age {
|
||||
// return 1
|
||||
// }
|
||||
}
|
||||
|
||||
var peoples = []people{
|
||||
{Name: "a", Age: 20},
|
||||
{Name: "b", Age: 10},
|
||||
{Name: "c", Age: 17},
|
||||
{Name: "d", Age: 8},
|
||||
{Name: "e", Age: 28},
|
||||
}
|
||||
comparator := &peopleAgeComparator{}
|
||||
sortedPeople := algorithm.InsertionSort(peoples, comparator)
|
||||
|
||||
fmt.Println(sortedSlice) //[{d 8} {b 10} {c 17} {a 20} {e 28}]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="SelectionSort">SelectionSort</span>
|
||||
<p>选择排序,参数comparator需要实现包lancetconstraints.Comparator</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func SelectionSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
sortedSlice := algorithm.SelectionSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="ShellSort">ShellSort</span>
|
||||
<p>希尔排序,参数comparator需要实现包lancetconstraints.Comparator</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ShellSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
sortedSlice := algorithm.ShellSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="QuickSort">QuickSort</span>
|
||||
<p>快速排序,参数comparator需要实现包lancetconstraints.Comparator</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func QuickSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) []T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
sortedSlice := algorithm.QuickSort(intSlice, 0, len(intSlice)-1, comparator)
|
||||
|
||||
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="HeapSort">HeapSort</span>
|
||||
<p>堆排序,参数comparator需要实现包lancetconstraints.Comparator</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func HeapSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
sortedSlice := algorithm.HeapSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="MergeSort">MergeSort</span>
|
||||
<p>归并排序,参数comparator需要实现包lancetconstraints.Comparator</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func MergeSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) []T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
sortedSlice := algorithm.MergeSort(intSlice, 0, len(intSlice)-1, comparator)
|
||||
|
||||
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="CountSort">CountSort</span>
|
||||
<p>计数排序,参数comparator需要实现包lancetconstraints.Comparator</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func CountSort[T any](slice []T, comparator lancetconstraints.Comparator) []T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
sortedSlice := algorithm.CountSort(intSlice, comparator)
|
||||
|
||||
fmt.Println(sortedSlice) //[]int{1, 2, 3, 4, 5, 6}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="BinarySearch">BinarySearch</span>
|
||||
<p>二分递归查找,返回元素索引,未找到元素返回-1,参数comparator需要实现包lancetconstraints.Comparator</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func BinarySearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var sortedNumbers = []int{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
comparator := &intComparator{}
|
||||
foundIndex := algorithm.BinarySearch(sortedNumbers, 5, 0, len(sortedNumbers)-1, comparator)
|
||||
fmt.Println(foundIndex) //4
|
||||
|
||||
notFoundIndex := algorithm.BinarySearch(sortedNumbers, 9, 0, len(sortedNumbers)-1, comparator)
|
||||
fmt.Println(notFoundIndex) //-1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="BinaryIterativeSearch">BinaryIterativeSearch</span>
|
||||
<p>二分迭代查找,返回元素索引,未找到元素返回-1,参数comparator需要实现包lancetconstraints.Comparator</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func BinaryIterativeSearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) int
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var sortedNumbers = []int{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
comparator := &intComparator{}
|
||||
foundIndex := algorithm.BinaryIterativeSearch(sortedNumbers, 5, 0, len(sortedNumbers)-1, comparator)
|
||||
fmt.Println(foundIndex) //4
|
||||
|
||||
notFoundIndex := algorithm.BinaryIterativeSearch(sortedNumbers, 9, 0, len(sortedNumbers)-1, comparator)
|
||||
fmt.Println(notFoundIndex) //-1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="LinearSearch">LinearSearch</span>
|
||||
<p>线性查找,返回元素索引,未找到元素返回-1,参数comparator需要实现包lancetconstraints.Comparator</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func LinearSearch[T any](slice []T, target T, comparator lancetconstraints.Comparator) int
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type intComparator struct{}
|
||||
|
||||
func (c *intComparator) Compare(v1 any, v2 any) int {
|
||||
val1, _ := v1.(int)
|
||||
val2, _ := v2.(int)
|
||||
|
||||
//ascending order
|
||||
if val1 < val2 {
|
||||
return -1
|
||||
} else if val1 > val2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
intSlice := []int{2, 1, 5, 3, 6, 4}
|
||||
comparator := &intComparator{}
|
||||
foundIndex := algorithm.LinearSearch(intSlice, 5, comparator)
|
||||
fmt.Println(foundIndex) //2
|
||||
|
||||
notFoundIndex := algorithm.LinearSearch(sortedNumbers, 0, comparator)
|
||||
fmt.Println(notFoundIndex) //-1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="LRUCache">LRUCache</span>
|
||||
<p>lru实现缓存</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func NewLRUCache[K comparable, V any](capacity int) *LRUCache[K, V]
|
||||
func (l *LRUCache[K, V]) Get(key K) (V, bool)
|
||||
func (l *LRUCache[K, V]) Put(key K, value V)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/algorithm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cache := algorithm.NewLRUCache[int, int](2)
|
||||
|
||||
cache.Put(1, 1)
|
||||
cache.Put(2, 2)
|
||||
|
||||
_, ok := cache.Get(0) // ok -> false
|
||||
|
||||
v, ok := cache.Get(1) // v->1, ok->true
|
||||
|
||||
}
|
||||
```
|
||||
349
docs/convertor.md
Normal file
349
docs/convertor.md
Normal file
@@ -0,0 +1,349 @@
|
||||
# Convertor
|
||||
Package convertor contains some functions for data type convertion.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source:
|
||||
|
||||
- [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>
|
||||
|
||||
## Usage:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [ColorHexToRGB](#ColorHexToRGB)
|
||||
- [ColorRGBToHex](#ColorRGBToHex)
|
||||
- [ToBool](#ToBool)
|
||||
- [ToBytes](#ToBytes)
|
||||
- [ToChar](#ToChar)
|
||||
- [ToInt](#ToInt)
|
||||
- [ToJson](#ToJson)
|
||||
- [ToString](#ToString)
|
||||
- [StructToMap](#StructToMap)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
|
||||
### <span id="ColorHexToRGB">ColorHexToRGB</span>
|
||||
<p>Convert color hex to color rgb.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ColorHexToRGB(colorHex string) (red, green, blue int)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
colorHex := "#003366"
|
||||
r, g, b := convertor.ColorHexToRGB(colorHex)
|
||||
fmt.Println(r, g, b) //0,51,102
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ColorRGBToHex">ColorRGBToHex</span>
|
||||
|
||||
<p>Convert color rgb to color hex.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ColorRGBToHex(red, green, blue int) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
r := 0
|
||||
g := 51
|
||||
b := 102
|
||||
colorHex := convertor.ColorRGBToHex(r, g, b)
|
||||
|
||||
fmt.Println(colorHex) //#003366
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToBool">ToBool</span>
|
||||
|
||||
<p>Convert string to a boolean value. Use strconv.ParseBool</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ToBool(s string) (bool, error)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
v1, _ := convertor.ToBool("1")
|
||||
fmt.Println(v1) //true
|
||||
|
||||
v2, _ := convertor.ToBool("true")
|
||||
fmt.Println(v2) //true
|
||||
|
||||
v3, _ := convertor.ToBool("True")
|
||||
fmt.Println(v3) //true
|
||||
|
||||
v4, _ := convertor.ToBool("123")
|
||||
fmt.Println(v4) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToBytes">ToBytes</span>
|
||||
|
||||
<p>Convert interface to byte slice.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ToBytes(data any) ([]byte, error)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
bytesData, err := convertor.ToBytes("0")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println(bytesData) //[]bytes{3, 4, 0, 0}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToChar">ToChar</span>
|
||||
|
||||
<p>Convert string to char slice.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ToChar(s string) []string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
chars := convertor.ToChar("")
|
||||
fmt.Println(chars) //[]string{""}
|
||||
|
||||
chars = convertor.ToChar("abc")
|
||||
fmt.Println(chars) //[]string{"a", "b", "c"}
|
||||
|
||||
chars = convertor.ToChar("1 2#3")
|
||||
fmt.Println(chars) //[]string{"1", " ", "2", "#", "3"}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToFloat">ToFloat</span>
|
||||
|
||||
<p>Convert interface to a float64 value. If param is a invalid floatable, will return 0 and error. </p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ToFloat(value any) (float64, error)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
v, err := convertor.ToFloat("")
|
||||
if err != nil {
|
||||
fmt.Println(err) //strconv.ParseFloat: parsing "": invalid syntax
|
||||
}
|
||||
fmt.Println(v) //0
|
||||
|
||||
v, _ = convertor.ToFloat("-.11")
|
||||
fmt.Println(v) //-0.11
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToInt">ToInt</span>
|
||||
|
||||
<p>Convert interface to a int64 value. If param is a invalid intable, will return 0 and error. </p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ToInt(value any) (int64, error)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
v, err := convertor.ToInt("")
|
||||
if err != nil {
|
||||
fmt.Println(err) //strconv.ParseInt: parsing "": invalid syntax
|
||||
}
|
||||
fmt.Println(v) //0
|
||||
|
||||
v, _ = convertor.ToFloat(1.12)
|
||||
fmt.Println(v) //1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToJson">ToJson</span>
|
||||
|
||||
<p>Convert interface to json string. If param can't be converted, will return "" and error. </p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ToJson(value any) (string, error)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var aMap = map[string]int{"a": 1, "b": 2, "c": 3}
|
||||
jsonStr, _ := convertor.ToJson(aMap)
|
||||
fmt.Printf("%q", jsonStr) //"{\"a\":1,\"b\":2,\"c\":3}"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToString">ToString</span>
|
||||
|
||||
<p>Convert interface to string. </p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ToString(value any) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Printf("%q", convertor.ToString(1)) //"1"
|
||||
fmt.Printf("%q", convertor.ToString(1.1)) //"1.1"
|
||||
fmt.Printf("%q", convertor.ToString([]int{1, 2, 3})) //"[1,2,3]"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="StructToMap">StructToMap</span>
|
||||
|
||||
<p>Convert struct to map, only convert exported field, struct field tag `json` should be set.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func StructToMap(value any) (map[string]any, error)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type People struct {
|
||||
Name string `json:"name"`
|
||||
age int
|
||||
}
|
||||
p := People{
|
||||
"test",
|
||||
100,
|
||||
}
|
||||
pm, _ := convertor.StructToMap(p)
|
||||
|
||||
fmt.Printf("type: %T, value: %s", pm, pm) //type: map[string]interface {}, value: map[name:test]
|
||||
}
|
||||
```
|
||||
351
docs/convertor_zh-CN.md
Normal file
351
docs/convertor_zh-CN.md
Normal file
@@ -0,0 +1,351 @@
|
||||
# Convertor
|
||||
convertor转换器包支持一些常见的数据类型转换
|
||||
|
||||
<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)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录
|
||||
|
||||
- [ColorHexToRGB](#ColorHexToRGB)
|
||||
- [ColorRGBToHex](#ColorRGBToHex)
|
||||
- [ToBool](#ToBool)
|
||||
- [ToBytes](#ToBytes)
|
||||
- [ToChar](#ToChar)
|
||||
- [ToInt](#ToInt)
|
||||
- [ToJson](#ToJson)
|
||||
- [ToString](#ToString)
|
||||
- [StructToMap](#StructToMap)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 文档
|
||||
|
||||
|
||||
|
||||
### <span id="ColorHexToRGB">ColorHexToRGB</span>
|
||||
<p>颜色值十六进制转rgb</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ColorHexToRGB(colorHex string) (red, green, blue int)
|
||||
```
|
||||
<b>列子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
colorHex := "#003366"
|
||||
r, g, b := convertor.ColorHexToRGB(colorHex)
|
||||
fmt.Println(r, g, b) //0,51,102
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ColorRGBToHex">ColorRGBToHex</span>
|
||||
|
||||
<p>颜色值rgb转十六进制</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ColorRGBToHex(red, green, blue int) string
|
||||
```
|
||||
<b>列子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
r := 0
|
||||
g := 51
|
||||
b := 102
|
||||
colorHex := convertor.ColorRGBToHex(r, g, b)
|
||||
|
||||
fmt.Println(colorHex) //#003366
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToBool">ToBool</span>
|
||||
|
||||
<p>字符串转布尔类型,使用strconv.ParseBool</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ToBool(s string) (bool, error)
|
||||
```
|
||||
<b>列子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
v1, _ := convertor.ToBool("1")
|
||||
fmt.Println(v1) //true
|
||||
|
||||
v2, _ := convertor.ToBool("true")
|
||||
fmt.Println(v2) //true
|
||||
|
||||
v3, _ := convertor.ToBool("True")
|
||||
fmt.Println(v3) //true
|
||||
|
||||
v4, _ := convertor.ToBool("123")
|
||||
fmt.Println(v4) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToBytes">ToBytes</span>
|
||||
|
||||
<p>interface转字节切片.</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ToBytes(data any) ([]byte, error)
|
||||
```
|
||||
<b>列子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
bytesData, err := convertor.ToBytes("0")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println(bytesData) //[]bytes{3, 4, 0, 0}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToChar">ToChar</span>
|
||||
|
||||
<p>字符串转字符切片</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ToChar(s string) []string
|
||||
```
|
||||
<b>列子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
chars := convertor.ToChar("")
|
||||
fmt.Println(chars) //[]string{""}
|
||||
|
||||
chars = convertor.ToChar("abc")
|
||||
fmt.Println(chars) //[]string{"a", "b", "c"}
|
||||
|
||||
chars = convertor.ToChar("1 2#3")
|
||||
fmt.Println(chars) //[]string{"1", " ", "2", "#", "3"}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToFloat">ToFloat</span>
|
||||
|
||||
<p>将interface转成float64类型,如果参数无法转换,会返回0和error</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ToFloat(value any) (float64, error)
|
||||
```
|
||||
<b>列子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
v, err := convertor.ToFloat("")
|
||||
if err != nil {
|
||||
fmt.Println(err) //strconv.ParseFloat: parsing "": invalid syntax
|
||||
}
|
||||
fmt.Println(v) //0
|
||||
|
||||
v, _ = convertor.ToFloat("-.11")
|
||||
fmt.Println(v) //-0.11
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToInt">ToInt</span>
|
||||
|
||||
<p>将interface转成intt64类型,如果参数无法转换,会返回0和error</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ToInt(value any) (int64, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
v, err := convertor.ToInt("")
|
||||
if err != nil {
|
||||
fmt.Println(err) //strconv.ParseInt: parsing "": invalid syntax
|
||||
}
|
||||
fmt.Println(v) //0
|
||||
|
||||
v, _ = convertor.ToFloat(1.12)
|
||||
fmt.Println(v) //1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToJson">ToJson</span>
|
||||
|
||||
<p>将interface转成json字符串,如果参数无法转换,会返回""和error</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ToJson(value any) (string, error)
|
||||
```
|
||||
<b>列子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var aMap = map[string]int{"a": 1, "b": 2, "c": 3}
|
||||
jsonStr, _ := convertor.ToJson(aMap)
|
||||
fmt.Printf("%q", jsonStr) //"{\"a\":1,\"b\":2,\"c\":3}"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToString">ToString</span>
|
||||
|
||||
<p>将interface转成字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ToString(value any) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Printf("%q", convertor.ToString(1)) //"1"
|
||||
fmt.Printf("%q", convertor.ToString(1.1)) //"1.1"
|
||||
fmt.Printf("%q", convertor.ToString([]int{1, 2, 3})) //"[1,2,3]"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="StructToMap">StructToMap</span>
|
||||
|
||||
<p>将struct转成map,只会转换struct中可导出的字段。struct中导出字段需要设置json tag标记</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func StructToMap(value any) (map[string]any, error)
|
||||
```
|
||||
<b>列子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type People struct {
|
||||
Name string `json:"name"`
|
||||
age int
|
||||
}
|
||||
p := People{
|
||||
"test",
|
||||
100,
|
||||
}
|
||||
pm, _ := convertor.StructToMap(p)
|
||||
|
||||
fmt.Printf("type: %T, value: %s", pm, pm) //type: map[string]interface {}, value: map[name:test]
|
||||
}
|
||||
```
|
||||
1033
docs/cryptor.md
Normal file
1033
docs/cryptor.md
Normal file
File diff suppressed because it is too large
Load Diff
1028
docs/cryptor_zh-CN.md
Normal file
1028
docs/cryptor_zh-CN.md
Normal file
File diff suppressed because it is too large
Load Diff
897
docs/datetime.md
Normal file
897
docs/datetime.md
Normal file
@@ -0,0 +1,897 @@
|
||||
# Datetime
|
||||
Package datetime supports date and time format and compare.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/datetime/datetime.go](https://github.com/duke-git/lancet/blob/main/datetime/datetime.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/datetime/conversion.go](https://github.com/duke-git/lancet/blob/main/datetime/conversion.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Usage:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [AddDay](#AddDay)
|
||||
- [AddHour](#AddHour)
|
||||
- [AddMinute](#AddMinute)
|
||||
- [BeginOfMinute](#BeginOfMinute)
|
||||
- [BeginOfHour](#BeginOfHour)
|
||||
- [BeginOfDay](#BeginOfDay)
|
||||
- [BeginOfWeek](#BeginOfWeek)
|
||||
- [BeginOfMonth](#BeginOfMonth)
|
||||
- [BeginOfYear](#BeginOfYear)
|
||||
- [EndOfMinute](#EndOfMinute)
|
||||
- [EndOfHour](#EndOfHour)
|
||||
- [EndOfDay](#EndOfDay)
|
||||
- [EndOfWeek](#EndOfWeek)
|
||||
- [EndOfMonth](#EndOfMonth)
|
||||
- [EndOfYear](#EndOfYear)
|
||||
- [GetNowDate](#GetNowDate)
|
||||
- [GetNowTime](#GetNowTime)
|
||||
- [GetNowDateTime](#GetNowDateTime)
|
||||
- [GetZeroHourTimestamp](#GetZeroHourTimestamp)
|
||||
- [GetNightTimestamp](#GetNightTimestamp)
|
||||
- [FormatTimeToStr](#FormatTimeToStr)
|
||||
- [FormatStrToTime](#FormatStrToTime)
|
||||
|
||||
- [NewUnixNow](#NewUnixNow)
|
||||
- [NewUnix](#NewUnix)
|
||||
- [NewFormat](#NewFormat)
|
||||
- [NewISO8601](#NewISO8601)
|
||||
- [ToUnix](#ToUnix)
|
||||
- [ToFormat](#ToFormat)
|
||||
- [ToFormatForTpl](#ToFormatForTpl)
|
||||
- [ToIso8601](#ToIso8601)
|
||||
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
## Note:
|
||||
1. 'format' string param in func FormatTimeToStr and FormatStrToTime function should be one of flows:
|
||||
- yyyy-mm-dd hh:mm:ss
|
||||
- yyyy-mm-dd hh:mm
|
||||
- yyyy-mm-dd hh
|
||||
- yyyy-mm-dd
|
||||
- yyyy-mm
|
||||
- mm-dd
|
||||
- dd-mm-yy hh:mm:ss
|
||||
- yyyy/mm/dd hh:mm:ss
|
||||
- yyyy/mm/dd hh:mm
|
||||
- yyyy-mm-dd hh
|
||||
- yyyy/mm/dd
|
||||
- yyyy/mm
|
||||
- mm/dd
|
||||
- dd/mm/yy hh:mm:ss
|
||||
- yyyy
|
||||
- mm
|
||||
- hh:mm:ss
|
||||
- mm:ss
|
||||
|
||||
|
||||
### <span id="AddDay">AddDay</span>
|
||||
<p>Add or sub days to time.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func AddDay(t time.Time, day int64) time.Time
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
after2Days := datetime.AddDay(now, 2)
|
||||
before2Days := datetime.AddDay(now, -2)
|
||||
|
||||
fmt.Println(after2Days, before2Days)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="AddHour">AddHour</span>
|
||||
<p>Add or sub hours to time.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func AddHour(t time.Time, hour int64) time.Time
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
after2Hours := datetime.AddHour(now, 2)
|
||||
before2Hours := datetime.AddHour(now, -2)
|
||||
|
||||
fmt.Println(after2Hours, after2Hours)
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="AddMinute">AddMinute</span>
|
||||
<p>Add or sub minutes to time.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func AddMinute(t time.Time, minute int64) time.Time
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
after2Minute := datetime.AddMinute(now, 2)
|
||||
before2Minute := datetime.AddMinute(now, -2)
|
||||
|
||||
fmt.Println(after2Minute, before2Minute)
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="BeginOfMinute">BeginOfMinute</span>
|
||||
<p>Return beginning minute time of day.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func BeginOfMinute(t time.Time) time.Time
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.BeginOfMinute(td)
|
||||
fmt.Println(bm) //2022-02-15 15:48:00 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="BeginOfHour">BeginOfHour</span>
|
||||
<p>Return zero time of day.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func BeginOfHour(t time.Time) time.Time
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.BeginOfHour(td)
|
||||
fmt.Println(bm) //2022-02-15 15:00:00 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="BeginOfDay">BeginOfDay</span>
|
||||
<p>Return begin time of day.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func BeginOfDay(t time.Time) time.Time
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.BeginOfDay(td)
|
||||
fmt.Println(bm) //2022-02-15 00:00:00 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="BeginOfWeek">BeginOfWeek</span>
|
||||
<p>Return beginning time of week, week begin from Sunday.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func BeginOfWeek(t time.Time) time.Time
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.BeginOfWeek(td)
|
||||
fmt.Println(bm) //2022-02-13 00:00:00 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="BeginOfMonth">BeginOfMonth</span>
|
||||
<p>Return beginning time of month</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func BeginOfMonth(t time.Time) time.Time
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.BeginOfMonth(td)
|
||||
fmt.Println(bm) //2022-02-01 00:00:00 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="BeginOfYear">BeginOfYear</span>
|
||||
<p>Return beginning time of year.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func BeginOfYear(t time.Time) time.Time
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.BeginOfYear(td)
|
||||
fmt.Println(bm) //2022-01-01 00:00:00 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="EndOfMinute">EndOfMinute</span>
|
||||
<p>Return end time minute of day.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func EndOfMinute(t time.Time) time.Time
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.EndOfMinute(td)
|
||||
fmt.Println(bm) //2022-02-15 15:48:59.999999999 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="EndOfHour">EndOfHour</span>
|
||||
<p>Return end time hour of day.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func EndOfHour(t time.Time) time.Time
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.EndOfHour(td)
|
||||
fmt.Println(bm) //2022-02-15 15:59:59.999999999 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="EndOfDay">EndOfDay</span>
|
||||
<p>Return end time hour of day.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func EndOfDay(t time.Time) time.Time
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.EndOfDay(td)
|
||||
fmt.Println(bm) //2022-02-15 23:59:59.999999999 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="EndOfWeek">EndOfWeek</span>
|
||||
<p>Return end time of week, week end with Saturday.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func EndOfWeek(t time.Time) time.Time
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.EndOfWeek(td)
|
||||
fmt.Println(bm) //2022-02-19 23:59:59.999999999 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="EndOfMonth">EndOfMonth</span>
|
||||
<p>Return end time of month</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func EndOfMonth(t time.Time) time.Time
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.EndOfMonth(td)
|
||||
fmt.Println(bm) //2022-02-28 23:59:59.999999999 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="EndOfYear">EndOfYear</span>
|
||||
<p>Return beginning time of year.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func EndOfYear(t time.Time) time.Time
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.EndOfYear(td)
|
||||
fmt.Println(bm) //2022-12-31 23:59:59.999999999 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="GetNowDate">GetNowDate</span>
|
||||
<p>Get current date string, format is yyyy-mm-dd.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func GetNowDate() string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
currentDate := datetime.GetNowDate()
|
||||
fmt.Println(currentDate) // 2022-01-28
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="GetNowTime">GetNowTime</span>
|
||||
<p>Get current time string, format is hh:mm:ss.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func GetNowTime() string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
currentTime := datetime.GetNowTime()
|
||||
fmt.Println(currentDate) // 15:57:33
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="GetNowDateTime">GetNowDateTime</span>
|
||||
<p>Get current date time string, format is yyyy-mm-dd hh:mm:ss.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func GetNowDateTime() string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
current := datetime.GetNowDateTime()
|
||||
fmt.Println(current) // 2022-01-28 15:59:33
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="GetZeroHourTimestamp">GetZeroHourTimestamp</span>
|
||||
<p>Return timestamp of zero hour (timestamp of 00:00).</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func GetZeroHourTimestamp() int64
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
zeroTime := datetime.GetZeroHourTimestamp()
|
||||
fmt.Println(zeroTime) // 1643299200
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="GetNightTimestamp">GetNightTimestamp</span>
|
||||
<p>Return timestamp of zero hour (timestamp of 23:59).</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func GetNightTimestamp() int64
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
nightTime := datetime.GetNightTimestamp()
|
||||
fmt.Println(nightTime) // 1643385599
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="FormatTimeToStr">FormatTimeToStr</span>
|
||||
<p>Format time to string, `format` param specification see note 1.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func FormatTimeToStr(t time.Time, format string) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
timeStr := datetime.FormatTimeToStr(now, "yyyy/mm/dd hh:mm:ss")
|
||||
fmt.Println(timeStr) //2022/01/28 16:07:44
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="FormatStrToTime">FormatStrToTime</span>
|
||||
<p>Format string to time, `format` param specification see note 1.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func FormatStrToTime(str, format string) (time.Time, error)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
time := datetime.FormatStrToTime("2006-01-02 15:04:05", "yyyy/mm/dd hh:mm:ss")
|
||||
fmt.Println(time)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="NewUnixNow">NewUnixNow</span>
|
||||
<p>Return unix timestamp of current time</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
type theTime struct {
|
||||
unix int64
|
||||
}
|
||||
func NewUnixNow() *theTime
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tm := datetime.NewUnixNow()
|
||||
fmt.Println(tm) //&{1647597438}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="NewUnix">NewUnix</span>
|
||||
<p>Return unix timestamp of specified int64 value.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
type theTime struct {
|
||||
unix int64
|
||||
}
|
||||
func NewUnix(unix int64) *theTime
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tm := datetime.NewUnix(1647597438)
|
||||
fmt.Println(tm) //&{1647597438}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="NewFormat">NewFormat</span>
|
||||
<p>Return unix timestamp of specified time string, t should be "yyyy-mm-dd hh:mm:ss".</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
type theTime struct {
|
||||
unix int64
|
||||
}
|
||||
func NewFormat(t string) (*theTime, error)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tm, err := datetime.NewFormat("2022-03-18 17:04:05")
|
||||
fmt.Println(tm) //&{1647594245}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="NewISO8601">NewISO8601</span>
|
||||
<p>Return unix timestamp of specified iso8601 time string.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
type theTime struct {
|
||||
unix int64
|
||||
}
|
||||
func NewISO8601(iso8601 string) (*theTime, error)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tm, err := datetime.NewISO8601("2006-01-02T15:04:05.999Z")
|
||||
fmt.Println(tm) //&{1136214245}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToUnix">ToUnix</span>
|
||||
<p>Return unix timestamp.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func (t *theTime) ToUnix() int64
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tm := datetime.NewUnixNow()
|
||||
fmt.Println(tm.ToUnix()) //1647597438
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToFormat">ToFormat</span>
|
||||
<p>Return time string 'yyyy-mm-dd hh:mm:ss'.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func (t *theTime) ToFormat() string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tm, _ := datetime.NewFormat("2022-03-18 17:04:05")
|
||||
fmt.Println(tm.ToFormat()) //"2022-03-18 17:04:05"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToFormatForTpl">ToFormatForTpl</span>
|
||||
<p>Return the time string which format is specified tpl.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func (t *theTime) ToFormatForTpl(tpl string) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tm, _ := datetime.NewFormat("2022-03-18 17:04:05")
|
||||
ts := tm.ToFormatForTpl("2006/01/02 15:04:05")
|
||||
fmt.Println(ts) //"2022/03/18 17:04:05"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="ToIso8601">ToIso8601</span>
|
||||
<p>Return iso8601 time string.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func (t *theTime) ToIso8601() string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tm, _ := datetime.NewISO8601("2006-01-02T15:04:05.999Z")
|
||||
ts := tm.ToIso8601()
|
||||
fmt.Println(ts) //"2006-01-02T23:04:05+08:00"
|
||||
}
|
||||
```
|
||||
893
docs/datetime_zh-CN.md
Normal file
893
docs/datetime_zh-CN.md
Normal file
@@ -0,0 +1,893 @@
|
||||
# Datetime
|
||||
datetime日期时间处理包,格式化日期,比较日期。
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/datetime/datetime.go](https://github.com/duke-git/lancet/blob/main/datetime/datetime.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录
|
||||
- [AddDay](#AddDay)
|
||||
- [AddHour](#AddHour)
|
||||
- [AddMinute](#AddMinute)
|
||||
- [BeginOfMinute](#BeginOfMinute)
|
||||
- [BeginOfHour](#BeginOfHour)
|
||||
- [BeginOfDay](#BeginOfDay)
|
||||
- [BeginOfWeek](#BeginOfWeek)
|
||||
- [BeginOfMonth](#BeginOfMonth)
|
||||
- [BeginOfYear](#BeginOfYear)
|
||||
- [EndOfMinute](#EndOfMinute)
|
||||
- [EndOfHour](#EndOfHour)
|
||||
- [EndOfDay](#EndOfDay)
|
||||
- [EndOfWeek](#EndOfWeek)
|
||||
- [EndOfMonth](#EndOfMonth)
|
||||
- [EndOfYear](#EndOfYear)
|
||||
- [GetNowDate](#GetNowDate)
|
||||
- [GetNowTime](#GetNowTime)
|
||||
- [GetNowDateTime](#GetNowDateTime)
|
||||
- [GetZeroHourTimestamp](#GetZeroHourTimestamp)
|
||||
- [GetNightTimestamp](#GetNightTimestamp)
|
||||
- [FormatTimeToStr](#FormatTimeToStr)
|
||||
- [FormatStrToTime](#FormatStrToTime)
|
||||
|
||||
- [NewUnixNow](#NewUnixNow)
|
||||
- [NewUnix](#NewUnix)
|
||||
- [NewFormat](#NewFormat)
|
||||
- [NewISO8601](#NewISO8601)
|
||||
- [ToUnix](#ToUnix)
|
||||
- [ToFormat](#ToFormat)
|
||||
- [ToFormatForTpl](#ToFormatForTpl)
|
||||
- [ToIso8601](#ToIso8601)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 文档
|
||||
|
||||
## 注:
|
||||
1. 方法FormatTimeToStr和FormatStrToTime中的format参数值需要传以下类型之一:
|
||||
- yyyy-mm-dd hh:mm:ss
|
||||
- yyyy-mm-dd hh:mm
|
||||
- yyyy-mm-dd hh
|
||||
- yyyy-mm-dd
|
||||
- yyyy-mm
|
||||
- mm-dd
|
||||
- dd-mm-yy hh:mm:ss
|
||||
- yyyy/mm/dd hh:mm:ss
|
||||
- yyyy/mm/dd hh:mm
|
||||
- yyyy-mm-dd hh
|
||||
- yyyy/mm/dd
|
||||
- yyyy/mm
|
||||
- mm/dd
|
||||
- dd/mm/yy hh:mm:ss
|
||||
- yyyy
|
||||
- mm
|
||||
- hh:mm:ss
|
||||
- mm:ss
|
||||
|
||||
|
||||
### <span id="AddDay">AddDay</span>
|
||||
<p>将日期加/减天数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func AddDay(t time.Time, day int64) time.Time
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
after2Days := datetime.AddDay(now, 2)
|
||||
before2Days := datetime.AddDay(now, -2)
|
||||
|
||||
fmt.Println(after2Days, before2Days)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="AddHour">AddHour</span>
|
||||
<p>将日期加/减小时数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func AddHour(t time.Time, hour int64) time.Time
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
after2Hours := datetime.AddHour(now, 2)
|
||||
before2Hours := datetime.AddHour(now, -2)
|
||||
|
||||
fmt.Println(after2Hours, after2Hours)
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="AddMinute">AddMinute</span>
|
||||
<p>将日期加/减分钟数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func AddMinute(t time.Time, minute int64) time.Time
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
after2Minute := datetime.AddMinute(now, 2)
|
||||
before2Minute := datetime.AddMinute(now, -2)
|
||||
|
||||
fmt.Println(after2Minute, before2Minute)
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="BeginOfMinute">BeginOfMinute</span>
|
||||
<p>返回指定时间的分钟开始时间</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func BeginOfMinute(t time.Time) time.Time
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.BeginOfMinute(td)
|
||||
fmt.Println(bm) //2022-02-15 15:48:00 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="BeginOfHour">BeginOfHour</span>
|
||||
<p>返回指定时间的小时开始时间</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func BeginOfHour(t time.Time) time.Time
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.BeginOfHour(td)
|
||||
fmt.Println(bm) //2022-02-15 15:00:00 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="BeginOfDay">BeginOfDay</span>
|
||||
<p>返回指定时间的当天开始时间</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func BeginOfDay(t time.Time) time.Time
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.BeginOfDay(td)
|
||||
fmt.Println(bm) //2022-02-15 00:00:00 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="BeginOfWeek">BeginOfWeek</span>
|
||||
<p>返回指定时间的星期开始时间</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func BeginOfWeek(t time.Time) time.Time
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.BeginOfWeek(td)
|
||||
fmt.Println(bm) //2022-02-13 00:00:00 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="BeginOfMonth">BeginOfMonth</span>
|
||||
<p>返回指定时间的当月开始时间</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func BeginOfMonth(t time.Time) time.Time
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.BeginOfMonth(td)
|
||||
fmt.Println(bm) //2022-02-01 00:00:00 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="BeginOfYear">BeginOfYear</span>
|
||||
<p>返回指定时间的当年开始时间</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func BeginOfYear(t time.Time) time.Time
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.BeginOfYear(td)
|
||||
fmt.Println(bm) //2022-01-01 00:00:00 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="EndOfMinute">EndOfMinute</span>
|
||||
<p>返回指定时间的分钟结束时间</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func EndOfMinute(t time.Time) time.Time
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.EndOfMinute(td)
|
||||
fmt.Println(bm) //2022-02-15 15:48:59.999999999 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="EndOfHour">EndOfHour</span>
|
||||
<p>返回指定时间的小时结束时间</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func EndOfHour(t time.Time) time.Time
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.EndOfHour(td)
|
||||
fmt.Println(bm) //2022-02-15 15:59:59.999999999 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="EndOfDay">EndOfDay</span>
|
||||
<p>返回指定时间的当天结束时间.</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func EndOfDay(t time.Time) time.Time
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.EndOfDay(td)
|
||||
fmt.Println(bm) //2022-02-15 23:59:59.999999999 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="EndOfWeek">EndOfWeek</span>
|
||||
<p>返回指定时间的星期结束时间</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func EndOfWeek(t time.Time) time.Time
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.EndOfWeek(td)
|
||||
fmt.Println(bm) //2022-02-19 23:59:59.999999999 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="EndOfMonth">EndOfMonth</span>
|
||||
<p>返回指定时间的月份结束时间</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func EndOfMonth(t time.Time) time.Time
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.EndOfMonth(td)
|
||||
fmt.Println(bm) //2022-02-28 23:59:59.999999999 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="EndOfYear">EndOfYear</span>
|
||||
<p>返回指定时间的年份结束时间</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func EndOfYear(t time.Time) time.Time
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
td := time.Date(2022, 2, 15, 15, 48, 40, 112, time.Local)
|
||||
bm := datetime.EndOfYear(td)
|
||||
fmt.Println(bm) //2022-12-31 23:59:59.999999999 +0800 CST
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="GetNowDate">GetNowDate</span>
|
||||
<p>获取当天日期,返回格式:yyyy-mm-dd</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func GetNowDate() string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
currentDate := datetime.GetNowDate()
|
||||
fmt.Println(currentDate) // 2022-01-28
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="GetNowTime">GetNowTime</span>
|
||||
<p>获取当时时间,返回格式:hh:mm:ss</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func GetNowTime() string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
currentTime := datetime.GetNowTime()
|
||||
fmt.Println(currentDate) // 15:57:33
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="GetNowDateTime">GetNowDateTime</span>
|
||||
<p>获取当时日期和时间,返回格式:yyyy-mm-dd hh:mm:ss.</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func GetNowDateTime() string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
current := datetime.GetNowDateTime()
|
||||
fmt.Println(current) // 2022-01-28 15:59:33
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="GetZeroHourTimestamp">GetZeroHourTimestamp</span>
|
||||
<p>获取零时时间戳(timestamp of 00:00).</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func GetZeroHourTimestamp() int64
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
zeroTime := datetime.GetZeroHourTimestamp()
|
||||
fmt.Println(zeroTime) // 1643299200
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="GetNightTimestamp">GetNightTimestamp</span>
|
||||
<p>获取午夜时间戳(timestamp of 23:59).</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func GetNightTimestamp() int64
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
nightTime := datetime.GetNightTimestamp()
|
||||
fmt.Println(nightTime) // 1643385599
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="FormatTimeToStr">FormatTimeToStr</span>
|
||||
<p>将日期格式化成字符串,`format` 参数格式参考注<sup>1</sup></p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func FormatTimeToStr(t time.Time, format string) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
timeStr := datetime.FormatTimeToStr(now, "yyyy/mm/dd hh:mm:ss")
|
||||
fmt.Println(timeStr) //2022/01/28 16:07:44
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="FormatStrToTime">FormatStrToTime</span>
|
||||
<p>将字符串格式化成时间,`format` 参数格式参考注<sup>1</sup></p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func FormatStrToTime(str, format string) (time.Time, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
time := datetime.FormatStrToTime("2006-01-02 15:04:05", "yyyy/mm/dd hh:mm:ss")
|
||||
fmt.Println(time)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="NewUnixNow">NewUnixNow</span>
|
||||
<p>创建一个当前时间的unix时间戳</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
type theTime struct {
|
||||
unix int64
|
||||
}
|
||||
func NewUnixNow() *theTime
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tm := datetime.NewUnixNow()
|
||||
fmt.Println(tm) //&{1647597438}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="NewUnix">NewUnix</span>
|
||||
<p>创建一个unix时间戳</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
type theTime struct {
|
||||
unix int64
|
||||
}
|
||||
func NewUnix(unix int64) *theTime
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tm := datetime.NewUnix(1647597438)
|
||||
fmt.Println(tm) //&{1647597438}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="NewFormat">NewFormat</span>
|
||||
<p>创建一个yyyy-mm-dd hh:mm:ss格式时间字符串的unix时间戳</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
type theTime struct {
|
||||
unix int64
|
||||
}
|
||||
func NewFormat(t string) (*theTime, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tm, err := datetime.NewFormat("2022-03-18 17:04:05")
|
||||
fmt.Println(tm) //&{1647594245}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="NewISO8601">NewISO8601</span>
|
||||
<p>创建一个iso8601格式时间字符串的unix时间戳</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
type theTime struct {
|
||||
unix int64
|
||||
}
|
||||
func NewISO8601(iso8601 string) (*theTime, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tm, err := datetime.NewISO8601("2006-01-02T15:04:05.999Z")
|
||||
fmt.Println(tm) //&{1136214245}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToUnix">ToUnix</span>
|
||||
<p>返回unix时间戳</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func (t *theTime) ToUnix() int64
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tm := datetime.NewUnixNow()
|
||||
fmt.Println(tm.ToUnix()) //1647597438
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToFormat">ToFormat</span>
|
||||
<p>返回格式'yyyy-mm-dd hh:mm:ss'的日期字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func (t *theTime) ToFormat() string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tm, _ := datetime.NewFormat("2022-03-18 17:04:05")
|
||||
fmt.Println(tm.ToFormat()) //"2022-03-18 17:04:05"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ToFormatForTpl">ToFormatForTpl</span>
|
||||
<p>返回tpl格式指定的日期字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func (t *theTime) ToFormatForTpl(tpl string) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tm, _ := datetime.NewFormat("2022-03-18 17:04:05")
|
||||
ts := tm.ToFormatForTpl("2006/01/02 15:04:05")
|
||||
fmt.Println(ts) //"2022/03/18 17:04:05"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="ToIso8601">ToIso8601</span>
|
||||
<p>返回iso8601日期字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func (t *theTime) ToIso8601() string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tm, _ := datetime.NewISO8601("2006-01-02T15:04:05.999Z")
|
||||
ts := tm.ToIso8601()
|
||||
fmt.Println(ts) //"2006-01-02T23:04:05+08:00"
|
||||
}
|
||||
```
|
||||
444
docs/fileutil.md
Normal file
444
docs/fileutil.md
Normal file
@@ -0,0 +1,444 @@
|
||||
# Fileutil
|
||||
Package fileutil implements some basic functions for file operations.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/fileutil/file.go](https://github.com/duke-git/lancet/blob/main/fileutil/file.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Usage:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [ClearFile](#ClearFile)
|
||||
- [CreateFile](#CreateFile)
|
||||
- [CopyFile](#CopyFile)
|
||||
- [FileMode](#FileMode)
|
||||
- [MiMeType](#MiMeType)
|
||||
- [IsExist](#IsExist)
|
||||
- [IsLink](#IsLink)
|
||||
- [IsDir](#IsDir)
|
||||
- [ListFileNames](#ListFileNames)
|
||||
- [RemoveFile](#RemoveFile)
|
||||
- [ReadFileToString](#ReadFileToString)
|
||||
- [ReadFileByLine](#ReadFileByLine)
|
||||
- [Zip](#Zip)
|
||||
|
||||
- [UnZip](#UnZip)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
|
||||
### <span id="ClearFile">ClearFile</span>
|
||||
<p>Clear the file content, write empty string to the file.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ClearFile(path string) error
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := fileutil.ClearFile("./test.txt")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="CreateFile">CreateFile</span>
|
||||
<p>Create file in path. return true if create succeed.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func CreateFile(path string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
isCreatedSucceed := fileutil.CreateFile("./test.txt")
|
||||
fmt.Println(isCreatedSucceed)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="CopyFile">CopyFile</span>
|
||||
<p>Copy src file to dest file. If dest file exist will overwrite it.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func CopyFile(srcFilePath string, dstFilePath string) error
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := fileutil.CopyFile("./test.txt", "./test_copy.txt")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="FileMode">FileMode</span>
|
||||
<p>Return file mode infomation.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func FileMode(path string) (fs.FileMode, error)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
mode, err := fileutil.FileMode("./test.txt")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println(mode)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="MiMeType">MiMeType</span>
|
||||
<p>Get file mime type, 'file' param's type should be string or *os.File.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func MiMeType(file any) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type1 := fileutil.MiMeType("./test.txt")
|
||||
fmt.Println(type1) //text/plain; charset=utf-8
|
||||
|
||||
f, _ := os.Open("./file.go")
|
||||
type2 := fileutil.MiMeType(f)
|
||||
fmt.Println(type2) //text/plain; charset=utf-8
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsExist">IsExist</span>
|
||||
<p>Checks if a file or directory exists.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsExist(path string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fileutil.CreateFile("./test.txt")
|
||||
isFileExist := fileutil.IsExist("./test.txt")
|
||||
fmt.Println(isFileExist) //true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="IsLink">IsLink</span>
|
||||
<p>Checks if a file is symbol link or not.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsLink(path string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
isLinkFile := fileutil.IsLink("./test.txt")
|
||||
fmt.Println(isLinkFile) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="IsDir">IsDir</span>
|
||||
<p>Checks if the path is directy or not.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsDir(path string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
isDir := fileutil.IsDir("./")
|
||||
fmt.Println(isDir) //true
|
||||
|
||||
isDir = fileutil.IsDir("./test.txt")
|
||||
fmt.Println(isDir) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ListFileNames">ListFileNames</span>
|
||||
<p>List all file names in given path.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ListFileNames(path string) ([]string, error)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fileNames, _ := fileutil.ListFileNames("./")
|
||||
fmt.Println(fileNames)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="RemoveFile">RemoveFile</span>
|
||||
<p>Remove the file of path.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func RemoveFile(path string) error
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := fileutil.RemoveFile("./test.txt")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="ReadFileToString">ReadFileToString</span>
|
||||
<p>Return string of file content.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ReadFileToString(path string) (string, error)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
path := "./test.txt"
|
||||
fileutil.CreateFile(path)
|
||||
|
||||
f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
|
||||
f.WriteString("hello world")
|
||||
|
||||
content, _ := fileutil.ReadFileToString(path)
|
||||
fmt.Println(content) //hello world
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ReadFileByLine">ReadFileByLine</span>
|
||||
<p>Read file line by line, and return slice of lines</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ReadFileByLine(path string)([]string, error)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
path := "./text.txt"
|
||||
fileutil.CreateFile(path)
|
||||
|
||||
f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
|
||||
defer f.Close()
|
||||
f.WriteString("hello\nworld")
|
||||
|
||||
contents, _ := fileutil.ReadFileByLine(path)
|
||||
fmt.Println(contents) //[]string{"hello", "world"}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Zip">Zip</span>
|
||||
<p>Create a zip file of fpath, fpath could be a file or a directory.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Zip(fpath string, destPath string) error
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := fileutil.Zip("./test.txt", "./test.zip")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="UnZip">UnZip</span>
|
||||
<p>Unzip the file and save it to dest path.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func UnZip(zipFile string, destPath string) error
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := fileutil.Zip("./test.zip", "./unzip/test.txt")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
444
docs/fileutil_zh-CN.md
Normal file
444
docs/fileutil_zh-CN.md
Normal file
@@ -0,0 +1,444 @@
|
||||
# Fileutil
|
||||
fileutil包支持文件基本操作。
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/fileutil/file.go](https://github.com/duke-git/lancet/blob/main/fileutil/file.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录
|
||||
- [ClearFile](#ClearFile)
|
||||
- [CreateFile](#CreateFile)
|
||||
- [CopyFile](#CopyFile)
|
||||
- [FileMode](#FileMode)
|
||||
- [MiMeType](#MiMeType)
|
||||
- [IsExist](#IsExist)
|
||||
- [IsLink](#IsLink)
|
||||
- [IsDir](#IsDir)
|
||||
|
||||
- [ListFileNames](#ListFileNames)
|
||||
- [RemoveFile](#RemoveFile)
|
||||
- [ReadFileToString](#ReadFileToString)
|
||||
- [ReadFileByLine](#ReadFileByLine)
|
||||
- [Zip](#Zip)
|
||||
- [UnZip](#UnZip)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 文档
|
||||
|
||||
|
||||
|
||||
### <span id="ClearFile">ClearFile</span>
|
||||
<p>清空文件内容</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ClearFile(path string) error
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := fileutil.ClearFile("./test.txt")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="CreateFile">CreateFile</span>
|
||||
<p>创建文件,创建成功返回true, 否则返回false</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func CreateFile(path string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
isCreatedSucceed := fileutil.CreateFile("./test.txt")
|
||||
fmt.Println(isCreatedSucceed)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="CopyFile">CopyFile</span>
|
||||
<p>拷贝文件,会覆盖原有的拷贝文件</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func CopyFile(srcFilePath string, dstFilePath string) error
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := fileutil.CopyFile("./test.txt", "./test_copy.txt")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="FileMode">FileMode</span>
|
||||
<p>获取文件mode信息</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func FileMode(path string) (fs.FileMode, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
mode, err := fileutil.FileMode("./test.txt")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println(mode)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="MiMeType">MiMeType</span>
|
||||
<p>获取文件mime类型, 'file'参数的类型必须是string或者*os.File</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func MiMeType(file any) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type1 := fileutil.MiMeType("./test.txt")
|
||||
fmt.Println(type1) //text/plain; charset=utf-8
|
||||
|
||||
f, _ := os.Open("./file.go")
|
||||
type2 := fileutil.MiMeType(f)
|
||||
fmt.Println(type2) //text/plain; charset=utf-8
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsExist">IsExist</span>
|
||||
<p>判断文件或目录是否存在</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsExist(path string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fileutil.CreateFile("./test.txt")
|
||||
isFileExist := fileutil.IsExist("./test.txt")
|
||||
fmt.Println(isFileExist) //true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="IsLink">IsLink</span>
|
||||
<p>判断文件是否是符号链接</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsLink(path string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
isLinkFile := fileutil.IsLink("./test.txt")
|
||||
fmt.Println(isLinkFile) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="IsDir">IsDir</span>
|
||||
<p>判断目录是否存在</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsDir(path string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
isDir := fileutil.IsDir("./")
|
||||
fmt.Println(isDir) //true
|
||||
|
||||
isDir = fileutil.IsDir("./test.txt")
|
||||
fmt.Println(isDir) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ListFileNames">ListFileNames</span>
|
||||
<p>返回目录下所有文件名</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ListFileNames(path string) ([]string, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fileNames, _ := fileutil.ListFileNames("./")
|
||||
fmt.Println(fileNames)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="RemoveFile">RemoveFile</span>
|
||||
<p>删除文件</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func RemoveFile(path string) error
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := fileutil.RemoveFile("./test.txt")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="ReadFileToString">ReadFileToString</span>
|
||||
<p>读取文件内容并返回字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ReadFileToString(path string) (string, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
path := "./test.txt"
|
||||
fileutil.CreateFile(path)
|
||||
|
||||
f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
|
||||
f.WriteString("hello world")
|
||||
|
||||
content, _ := fileutil.ReadFileToString(path)
|
||||
fmt.Println(content) //hello world
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ReadFileByLine">ReadFileByLine</span>
|
||||
<p>按行读取文件内容,返回字符串切片包含每一行</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ReadFileByLine(path string)([]string, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
path := "./text.txt"
|
||||
fileutil.CreateFile(path)
|
||||
|
||||
f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
|
||||
defer f.Close()
|
||||
f.WriteString("hello\nworld")
|
||||
|
||||
contents, _ := fileutil.ReadFileByLine(path)
|
||||
fmt.Println(contents) //[]string{"hello", "world"}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Zip">Zip</span>
|
||||
<p>zip压缩文件, fpath参数可以是文件或目录</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Zip(fpath string, destPath string) error
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := fileutil.Zip("./test.txt", "./test.zip")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="UnZip">UnZip</span>
|
||||
<p>zip解压缩文件并保存在目录中</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func UnZip(zipFile string, destPath string) error
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := fileutil.Zip("./test.zip", "./unzip/test.txt")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
53
docs/formatter.md
Normal file
53
docs/formatter.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Formatter
|
||||
formatter contains some functions for data formatting.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/formatter/formatter.go](https://github.com/duke-git/lancet/blob/main/formatter/formatter.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Usage:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/formatter"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [Comma](#Comma)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
|
||||
### <span id="Comma">Comma</span>
|
||||
<p>Add comma to number by every 3 numbers from right. ahead by symbol char.
|
||||
Param should be number or numberic string.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Comma(v any, symbol string) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/formatter"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(formatter.Comma("12345", "")) // "12,345"
|
||||
fmt.Println(formatter.Comma(12345.67, "¥")) // "¥12,345.67"
|
||||
}
|
||||
```
|
||||
52
docs/formatter_zh-CN.md
Normal file
52
docs/formatter_zh-CN.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# Formatter
|
||||
formatter格式化器包含一些数据格式化处理方法。
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/formatter/formatter.go](https://github.com/duke-git/lancet/blob/main/formatter/formatter.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/formatter"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录
|
||||
- [Comma](#Comma)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 文档
|
||||
|
||||
|
||||
|
||||
### <span id="Comma">Comma</span>
|
||||
<p>用逗号每隔3位分割数字/字符串,签名添加符号。参数必须是数字或者可以转为数字的字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Comma(v any, symbol string) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/formatter"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(formatter.Comma("12345", "")) // "12,345"
|
||||
fmt.Println(formatter.Comma(12345.67, "¥")) // "¥12,345.67"
|
||||
}
|
||||
```
|
||||
364
docs/function.md
Normal file
364
docs/function.md
Normal file
@@ -0,0 +1,364 @@
|
||||
# Function
|
||||
Package function can control the flow of function execution and support part of functional programming.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/function/function.go](https://github.com/duke-git/lancet/blob/main/function/function.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/function/watcher.go](https://github.com/duke-git/lancet/blob/main/function/watcher.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Usage:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/function"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [After](#After)
|
||||
- [Before](#Before)
|
||||
- [Curry](#Curry)
|
||||
- [Compose](#Compose)
|
||||
- [Debounced](#Debounced)
|
||||
- [Delay](#Delay)
|
||||
- [Watcher](#Watcher)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
|
||||
### <span id="After">After</span>
|
||||
<p>Creates a function that invokes given func once it's called n or more times.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func After(n int, fn any) func(args ...any) []reflect.Value
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/function"
|
||||
)
|
||||
|
||||
func main() {
|
||||
arr := []string{"a", "b"}
|
||||
f := function.After(len(arr), func(i int) int {
|
||||
fmt.Println("last print")
|
||||
return i
|
||||
})
|
||||
|
||||
type cb func(args ...any) []reflect.Value
|
||||
print := func(i int, s string, fn cb) {
|
||||
fmt.Printf("arr[%d] is %s \n", i, s)
|
||||
fn(i)
|
||||
}
|
||||
|
||||
fmt.Println("arr is", arr)
|
||||
for i := 0; i < len(arr); i++ {
|
||||
print(i, arr[i], f)
|
||||
}
|
||||
|
||||
//output:
|
||||
// arr is [a b]
|
||||
// arr[0] is a
|
||||
// arr[1] is b
|
||||
// last print
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Before">Before</span>
|
||||
|
||||
<p>creates a function that invokes func once it's called less than n times.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Before(n int, fn any) func(args ...any) []reflect.Value
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/function"
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func main() {
|
||||
assert := internal.NewAssert(t, "TestBefore")
|
||||
|
||||
arr := []string{"a", "b", "c", "d", "e"}
|
||||
f := function.Before(3, func(i int) int {
|
||||
return i
|
||||
})
|
||||
|
||||
var res []int64
|
||||
type cb func(args ...any) []reflect.Value
|
||||
appendStr := func(i int, s string, fn cb) {
|
||||
v := fn(i)
|
||||
res = append(res, v[0].Int())
|
||||
}
|
||||
|
||||
for i := 0; i < len(arr); i++ {
|
||||
appendStr(i, arr[i], f)
|
||||
}
|
||||
|
||||
expected := []int64{0, 1, 2, 2, 2}
|
||||
assert.Equal(expected, res)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Curry">Curry</span>
|
||||
|
||||
<p>Make a curry function.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
type Fn func(...any) any
|
||||
func (f Fn) Curry(i any) func(...any) any
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/function"
|
||||
)
|
||||
|
||||
func main() {
|
||||
add := func(a, b int) int {
|
||||
return a + b
|
||||
}
|
||||
var addCurry function.Fn = func(values ...any) any {
|
||||
return add(values[0].(int), values[1].(int))
|
||||
}
|
||||
add1 := addCurry.Curry(1)
|
||||
result := add1(2)
|
||||
fmt.Println(result) //3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Compose">Compose</span>
|
||||
|
||||
<p>Compose the function list from right to left, then return the composed function.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Compose(fnList ...func(...any) any) func(...any) any
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/function"
|
||||
)
|
||||
|
||||
func main() {
|
||||
add1 := func(v ...any) any {
|
||||
return v[0].(int) + 1
|
||||
}
|
||||
add2 := func(v ...any) any {
|
||||
return v[0].(int) + 2
|
||||
}
|
||||
|
||||
add3 := function.Compose(add1, add2)
|
||||
result := add3(1)
|
||||
|
||||
fmt.Println(result) //4
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Debounced">Debounced</span>
|
||||
|
||||
<p>Creates a debounced function that delays invoking fn until after wait duration have elapsed since the last time the debounced function was invoked.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Debounced(fn func(), duration time.Duration) func()
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/function"
|
||||
)
|
||||
|
||||
func main() {
|
||||
count := 0
|
||||
add := func() {
|
||||
count++
|
||||
}
|
||||
|
||||
debouncedAdd := function.Debounced(add, 50*time.Microsecond)
|
||||
function.debouncedAdd()
|
||||
function.debouncedAdd()
|
||||
function.debouncedAdd()
|
||||
function.debouncedAdd()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
fmt.Println(count) //1
|
||||
|
||||
function.debouncedAdd()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
fmt.Println(count) //2
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Delay">Delay</span>
|
||||
|
||||
<p>Invoke function after delayed time.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Delay(delay time.Duration, fn any, args ...any)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/function"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var print = func(s string) {
|
||||
fmt.Println(count) //test delay
|
||||
}
|
||||
function.Delay(2*time.Second, print, "test delay")
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Schedule">Schedule</span>
|
||||
|
||||
<p>Invoke function every duration time, until close the returned bool chan.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Schedule(d time.Duration, fn any, args ...any) chan bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/function"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var res []string
|
||||
appendStr := func(s string) {
|
||||
res = append(res, s)
|
||||
}
|
||||
|
||||
stop := function.Schedule(1*time.Second, appendStr, "*")
|
||||
time.Sleep(5 * time.Second)
|
||||
close(stop)
|
||||
|
||||
fmt.Println(res) //[* * * * *]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Watcher">Watcher</span>
|
||||
|
||||
<p>Watcher is used for record code excution time. can start/stop/reset the watch timer. get the elapsed time of function execution.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
type Watcher struct {
|
||||
startTime int64
|
||||
stopTime int64
|
||||
excuting bool
|
||||
}
|
||||
func (w *Watcher) Start() //start the watcher
|
||||
func (w *Watcher) Stop() //stop the watcher
|
||||
func (w *Watcher) Reset() //reset the watcher
|
||||
func (w *Watcher) GetElapsedTime() time.Duration //get the elapsed time of function execution
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/function"
|
||||
)
|
||||
|
||||
func main() {
|
||||
w := &function.Watcher{}
|
||||
w.Start()
|
||||
|
||||
longRunningTask()
|
||||
|
||||
fmt.Println(w.excuting) //true
|
||||
|
||||
w.Stop()
|
||||
|
||||
eapsedTime := w.GetElapsedTime().Milliseconds()
|
||||
fmt.Println(eapsedTime)
|
||||
|
||||
w.Reset()
|
||||
|
||||
fmt.Println(w.excuting) //false
|
||||
|
||||
fmt.Println(w.startTime) //0
|
||||
fmt.Println(w.stopTime) //0
|
||||
}
|
||||
|
||||
func longRunningTask() {
|
||||
var slice []int64
|
||||
for i := 0; i < 10000000; i++ {
|
||||
slice = append(slice, int64(i))
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
364
docs/function_zh-CN.md
Normal file
364
docs/function_zh-CN.md
Normal file
@@ -0,0 +1,364 @@
|
||||
# Function
|
||||
function函数包控制函数执行流程,包含部分函数式编程。
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/function/function.go](https://github.com/duke-git/lancet/blob/main/function/function.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/function/watcher.go](https://github.com/duke-git/lancet/blob/main/function/watcher.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/function"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录
|
||||
- [After](#After)
|
||||
- [Before](#Before)
|
||||
- [Curry](#Curry)
|
||||
- [Compose](#Compose)
|
||||
- [Debounced](#Debounced)
|
||||
- [Delay](#Delay)
|
||||
- [Watcher](#Watcher)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 文档
|
||||
|
||||
|
||||
|
||||
### <span id="After">After</span>
|
||||
<p>创建一个函数,当他被调用n或更多次之后将马上触发fn</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func After(n int, fn any) func(args ...any) []reflect.Value
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/function"
|
||||
)
|
||||
|
||||
func main() {
|
||||
arr := []string{"a", "b"}
|
||||
f := function.After(len(arr), func(i int) int {
|
||||
fmt.Println("last print")
|
||||
return i
|
||||
})
|
||||
|
||||
type cb func(args ...any) []reflect.Value
|
||||
print := func(i int, s string, fn cb) {
|
||||
fmt.Printf("arr[%d] is %s \n", i, s)
|
||||
fn(i)
|
||||
}
|
||||
|
||||
fmt.Println("arr is", arr)
|
||||
for i := 0; i < len(arr); i++ {
|
||||
print(i, arr[i], f)
|
||||
}
|
||||
|
||||
//output:
|
||||
// arr is [a b]
|
||||
// arr[0] is a
|
||||
// arr[1] is b
|
||||
// last print
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Before">Before</span>
|
||||
|
||||
<p>创建一个函数,调用次数不超过n次,之后再调用这个函数,将返回一次最后调用fn的结果</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Before(n int, fn any) func(args ...any) []reflect.Value
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/function"
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func main() {
|
||||
assert := internal.NewAssert(t, "TestBefore")
|
||||
|
||||
arr := []string{"a", "b", "c", "d", "e"}
|
||||
f := function.Before(3, func(i int) int {
|
||||
return i
|
||||
})
|
||||
|
||||
var res []int64
|
||||
type cb func(args ...any) []reflect.Value
|
||||
appendStr := func(i int, s string, fn cb) {
|
||||
v := fn(i)
|
||||
res = append(res, v[0].Int())
|
||||
}
|
||||
|
||||
for i := 0; i < len(arr); i++ {
|
||||
appendStr(i, arr[i], f)
|
||||
}
|
||||
|
||||
expected := []int64{0, 1, 2, 2, 2}
|
||||
assert.Equal(expected, res)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Curry">Curry</span>
|
||||
|
||||
<p>创建一个柯里化的函数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
type Fn func(...any) any
|
||||
func (f Fn) Curry(i any) func(...any) any
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/function"
|
||||
)
|
||||
|
||||
func main() {
|
||||
add := func(a, b int) int {
|
||||
return a + b
|
||||
}
|
||||
var addCurry function.Fn = func(values ...any) any {
|
||||
return add(values[0].(int), values[1].(int))
|
||||
}
|
||||
add1 := addCurry.Curry(1)
|
||||
result := add1(2)
|
||||
fmt.Println(result) //3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Compose">Compose</span>
|
||||
|
||||
<p>从右至左组合函数列表fnList, 返回组合后的函数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Compose(fnList ...func(...any) any) func(...any) any
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/function"
|
||||
)
|
||||
|
||||
func main() {
|
||||
add1 := func(v ...any) any {
|
||||
return v[0].(int) + 1
|
||||
}
|
||||
add2 := func(v ...any) any {
|
||||
return v[0].(int) + 2
|
||||
}
|
||||
|
||||
add3 := function.Compose(add1, add2)
|
||||
result := add3(1)
|
||||
|
||||
fmt.Println(result) //4
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Debounced">Debounced</span>
|
||||
|
||||
<p>创建一个 debounced 函数,该函数延迟调用 fn 直到自上次调用 debounced 函数后等待持续时间过去。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Debounced(fn func(), duration time.Duration) func()
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/function"
|
||||
)
|
||||
|
||||
func main() {
|
||||
count := 0
|
||||
add := func() {
|
||||
count++
|
||||
}
|
||||
|
||||
debouncedAdd := function.Debounced(add, 50*time.Microsecond)
|
||||
function.debouncedAdd()
|
||||
function.debouncedAdd()
|
||||
function.debouncedAdd()
|
||||
function.debouncedAdd()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
fmt.Println(count) //1
|
||||
|
||||
function.debouncedAdd()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
fmt.Println(count) //2
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Delay">Delay</span>
|
||||
|
||||
<p>延迟delay时间后调用函数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Delay(delay time.Duration, fn any, args ...any)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/function"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var print = func(s string) {
|
||||
fmt.Println(count) //test delay
|
||||
}
|
||||
function.Delay(2*time.Second, print, "test delay")
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Schedule">Schedule</span>
|
||||
|
||||
<p>每次持续时间调用函数,直到关闭返回的 bool chan</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Schedule(d time.Duration, fn any, args ...any) chan bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/function"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var res []string
|
||||
appendStr := func(s string) {
|
||||
res = append(res, s)
|
||||
}
|
||||
|
||||
stop := function.Schedule(1*time.Second, appendStr, "*")
|
||||
time.Sleep(5 * time.Second)
|
||||
close(stop)
|
||||
|
||||
fmt.Println(res) //[* * * * *]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Watcher">Watcher</span>
|
||||
|
||||
<p>Watcher 用于记录代码执行时间。可以启动/停止/重置手表定时器。获取函数执行的时间。 </p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
type Watcher struct {
|
||||
startTime int64
|
||||
stopTime int64
|
||||
excuting bool
|
||||
}
|
||||
func (w *Watcher) Start() //start the watcher
|
||||
func (w *Watcher) Stop() //stop the watcher
|
||||
func (w *Watcher) Reset() //reset the watcher
|
||||
func (w *Watcher) GetElapsedTime() time.Duration //get the elapsed time of function execution
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/function"
|
||||
)
|
||||
|
||||
func main() {
|
||||
w := &function.Watcher{}
|
||||
w.Start()
|
||||
|
||||
longRunningTask()
|
||||
|
||||
fmt.Println(w.excuting) //true
|
||||
|
||||
w.Stop()
|
||||
|
||||
eapsedTime := w.GetElapsedTime().Milliseconds()
|
||||
fmt.Println(eapsedTime)
|
||||
|
||||
w.Reset()
|
||||
|
||||
fmt.Println(w.excuting) //false
|
||||
|
||||
fmt.Println(w.startTime) //0
|
||||
fmt.Println(w.stopTime) //0
|
||||
}
|
||||
|
||||
func longRunningTask() {
|
||||
var slice []int64
|
||||
for i := 0; i < 10000000; i++ {
|
||||
slice = append(slice, int64(i))
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
320
docs/mathutil.md
Normal file
320
docs/mathutil.md
Normal file
@@ -0,0 +1,320 @@
|
||||
# Mathutil
|
||||
Package mathutil implements some functions for math calculation.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Example:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [Average](#Average)
|
||||
- [Exponent](#Exponent)
|
||||
- [Fibonacci](#Fibonacci)
|
||||
- [Factorial](#Factorial)
|
||||
- [Max](#Max)
|
||||
- [Min](#Min)
|
||||
|
||||
- [Percent](#Percent)
|
||||
- [RoundToFloat](#RoundToFloat)
|
||||
- [RoundToString](#RoundToString)
|
||||
- [TruncRound](#TruncRound)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
|
||||
### <span id="Average">Average</span>
|
||||
<p>Return average value of numbers. Maybe call RoundToFloat to round result.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Average[T lancetconstraints.Number](numbers ...T) T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Average(0, 0)) //0
|
||||
fmt.Println(mathutil.Average(1, 1)) //1
|
||||
avg := mathutil.Average(1.2, 1.4) //1.2999999998
|
||||
roundAvg := mmathutil.RoundToFloat(avg, 1) // 1.3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Exponent">Exponent</span>
|
||||
<p>Calculate x to the nth power.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Exponent(x, n int64) int64
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Exponent(10, 0)) //1
|
||||
fmt.Println(mathutil.Exponent(10, 1)) //10
|
||||
fmt.Println(mathutil.Exponent(10, 2)) //100
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Fibonacci">Fibonacci</span>
|
||||
<p>Calculate the nth number of fibonacci sequence.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Fibonacci(first, second, n int) int
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Fibonacci(1, 1, 1)) //1
|
||||
fmt.Println(mathutil.Fibonacci(1, 1, 2)) //1
|
||||
fmt.Println(mathutil.Fibonacci(1, 1, 3)) //2
|
||||
fmt.Println(mathutil.Fibonacci(1, 1, 4)) //3
|
||||
fmt.Println(mathutil.Fibonacci(1, 1, 5)) //5
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Factorial">Factorial</span>
|
||||
<p>Calculate the factorial of x.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Factorial(x uint) uint
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Factorial(0)) //1
|
||||
fmt.Println(mathutil.Factorial(1)) //1
|
||||
fmt.Println(mathutil.Factorial(2)) //2
|
||||
fmt.Println(mathutil.Factorial(3)) //6
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Max">Max</span>
|
||||
<p>Return max value of numbers.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Max[T lancetconstraints.Number](numbers ...T) T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Max(0, 0)) //0
|
||||
fmt.Println(mathutil.Max(1, 2, 3)) //3
|
||||
fmt.Println(mathutil.Max(1.2, 1.4, 1.1, 1.4)) //1.4
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Min">Min</span>
|
||||
<p>Return min value of numbers.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Min[T lancetconstraints.Number](numbers ...T) T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Min(0, 0)) //0
|
||||
fmt.Println(mathutil.Min(1, 2, 3)) //1
|
||||
fmt.Println(mathutil.Min(1.2, 1.4, 1.1, 1.4)) //1.1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Percent">Percent</span>
|
||||
<p>calculate the percentage of val to total, retain n decimal places.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Percent(val, total float64, n int) float64
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Percent(1, 2, 2)) //1
|
||||
fmt.Println(mathutil.Percent(0.1, 0.3, 2)) //33.33
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="RoundToFloat">RoundToFloat</span>
|
||||
<p>Round float up to n decimal places.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func RoundToFloat(x float64, n int) float64
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.RoundToFloat(0, 0)) //0
|
||||
fmt.Println(mathutil.RoundToFloat(0, 1)) //0
|
||||
fmt.Println(mathutil.RoundToFloat(0.124, 2)) //0.12
|
||||
fmt.Println(mathutil.RoundToFloat(0.125, 2)) //0.13
|
||||
fmt.Println(mathutil.RoundToFloat(0.125, 3)) //0.125
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="RoundToString">RoundToString</span>
|
||||
<p>Round float up to n decimal places. will return string.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func RoundToString(x float64, n int) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.RoundToString(0, 0)) //"0"
|
||||
fmt.Println(mathutil.RoundToString(0, 1)) //"0.0:
|
||||
fmt.Println(mathutil.RoundToString(0.124, 2)) //"0.12"
|
||||
fmt.Println(mathutil.RoundToString(0.125, 2)) //"0.13"
|
||||
fmt.Println(mathutil.RoundToString(0.125, 3)) //"0.125"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="TruncRound">TruncRound</span>
|
||||
<p>Round float off n decimal places.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func TruncRound(x float64, n int) float64
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.TruncRound(0, 0)) //0
|
||||
fmt.Println(mathutil.TruncRound(0, 1)) //0
|
||||
fmt.Println(mathutil.TruncRound(0.124, 2)) //0.12
|
||||
fmt.Println(mathutil.TruncRound(0.125, 2)) //0.12
|
||||
fmt.Println(mathutil.TruncRound(0.125, 3)) //0.125
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
317
docs/mathutil_zh-CN.md
Normal file
317
docs/mathutil_zh-CN.md
Normal file
@@ -0,0 +1,317 @@
|
||||
# Mathutil
|
||||
mathutil包实现了一些数学计算的函数.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录
|
||||
- [Average](#Average)
|
||||
- [Exponent](#Exponent)
|
||||
- [Fibonacci](#Fibonacci)
|
||||
- [Factorial](#Factorial)
|
||||
- [Max](#Max)
|
||||
- [Min](#Min)
|
||||
|
||||
- [Percent](#Percent)
|
||||
- [RoundToFloat](#RoundToFloat)
|
||||
- [RoundToString](#RoundToString)
|
||||
- [TruncRound](#TruncRound)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
### <span id="Average">Average</span>
|
||||
<p>计算平均数. 可能需要对结果调用RoundToFloat方法四舍五入</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Average[T lancetconstraints.Number](numbers ...T) T
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Average(0, 0)) //0
|
||||
fmt.Println(mathutil.Average(1, 1)) //1
|
||||
avg := mathutil.Average(1.2, 1.4) //1.2999999998
|
||||
roundAvg := mmathutil.RoundToFloat(avg, 1) // 1.3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="Exponent">Exponent</span>
|
||||
<p>指数计算(x的n次方)</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Exponent(x, n int64) int64
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Exponent(10, 0)) //1
|
||||
fmt.Println(mathutil.Exponent(10, 1)) //10
|
||||
fmt.Println(mathutil.Exponent(10, 2)) //100
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Fibonacci">Fibonacci</span>
|
||||
<p>计算斐波那契数列的第n个数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Fibonacci(first, second, n int) int
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Fibonacci(1, 1, 1)) //1
|
||||
fmt.Println(mathutil.Fibonacci(1, 1, 2)) //1
|
||||
fmt.Println(mathutil.Fibonacci(1, 1, 3)) //2
|
||||
fmt.Println(mathutil.Fibonacci(1, 1, 4)) //3
|
||||
fmt.Println(mathutil.Fibonacci(1, 1, 5)) //5
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Factorial">Factorial</span>
|
||||
<p>计算阶乘</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Factorial(x uint) uint
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Factorial(0)) //1
|
||||
fmt.Println(mathutil.Factorial(1)) //1
|
||||
fmt.Println(mathutil.Factorial(2)) //2
|
||||
fmt.Println(mathutil.Factorial(3)) //6
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="Max">Max</span>
|
||||
<p>返回参数中的最大数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Max[T lancetconstraints.Number](numbers ...T) T
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Max(0, 0)) //0
|
||||
fmt.Println(mathutil.Max(1, 2, 3)) //3
|
||||
fmt.Println(mathutil.Max(1.2, 1.4, 1.1, 1.4)) //1.4
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Min">Min</span>
|
||||
<p>返回参数中的最小数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Min[T lancetconstraints.Number](numbers ...T) T
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Min(0, 0)) //0
|
||||
fmt.Println(mathutil.Min(1, 2, 3)) //1
|
||||
fmt.Println(mathutil.Min(1.2, 1.4, 1.1, 1.4)) //1.1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Percent">Percent</span>
|
||||
<p>计算百分比,保留n位小数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Percent(val, total float64, n int) float64
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.Percent(1, 2, 2)) //1
|
||||
fmt.Println(mathutil.Percent(0.1, 0.3, 2)) //33.33
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="RoundToFloat">RoundToFloat</span>
|
||||
<p>四舍五入,保留n位小数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func RoundToFloat(x float64, n int) float64
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.RoundToFloat(0, 0)) //0
|
||||
fmt.Println(mathutil.RoundToFloat(0, 1)) //0
|
||||
fmt.Println(mathutil.RoundToFloat(0.124, 2)) //0.12
|
||||
fmt.Println(mathutil.RoundToFloat(0.125, 2)) //0.13
|
||||
fmt.Println(mathutil.RoundToFloat(0.125, 3)) //0.125
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="RoundToString">RoundToString</span>
|
||||
<p>四舍五入,保留n位小数,返回字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func RoundToString(x float64, n int) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.RoundToString(0, 0)) //"0"
|
||||
fmt.Println(mathutil.RoundToString(0, 1)) //"0.0:
|
||||
fmt.Println(mathutil.RoundToString(0.124, 2)) //"0.12"
|
||||
fmt.Println(mathutil.RoundToString(0.125, 2)) //"0.13"
|
||||
fmt.Println(mathutil.RoundToString(0.125, 3)) //"0.125"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="TruncRound">TruncRound</span>
|
||||
<p>截短n位小数(不进行四舍五入)</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func TruncRound(x float64, n int) float64
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(mathutil.TruncRound(0, 0)) //0
|
||||
fmt.Println(mathutil.TruncRound(0, 1)) //0
|
||||
fmt.Println(mathutil.TruncRound(0.124, 2)) //0.12
|
||||
fmt.Println(mathutil.TruncRound(0.125, 2)) //0.12
|
||||
fmt.Println(mathutil.TruncRound(0.125, 3)) //0.125
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
511
docs/netutil.md
Normal file
511
docs/netutil.md
Normal file
@@ -0,0 +1,511 @@
|
||||
# Netutil
|
||||
Package netutil contains functions to get net information and send http request.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/netutil/net.go](https://github.com/duke-git/lancet/blob/main/netutil/net.go)
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/netutil/http.go](https://github.com/duke-git/lancet/blob/main/netutil/http.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Usage:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [ConvertMapToQueryString](#ConvertMapToQueryString)
|
||||
- [GetInternalIp](#GetInternalIp)
|
||||
- [GetIps](#GetIps)
|
||||
- [GetMacAddrs](#GetMacAddrs)
|
||||
- [GetPublicIpInfo](#GetPublicIpInfo)
|
||||
- [IsPublicIP](#IsPublicIP)
|
||||
- [HttpGet](#HttpGet)
|
||||
- [HttpDelete](#HttpDelete)
|
||||
- [HttpPost](#HttpPost)
|
||||
- [HttpPut](#HttpPut)
|
||||
|
||||
- [HttpPatch](#HttpPatch)
|
||||
- [ParseHttpResponse](#ParseHttpResponse)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
### <span id="ConvertMapToQueryString">ConvertMapToQueryString</span>
|
||||
<p>Convert map to url query string.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ConvertMapToQueryString(param map[string]any) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var m = map[string]any{
|
||||
"c": 3,
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
}
|
||||
qs := netutil.ConvertMapToQueryString(m)
|
||||
|
||||
fmt.Println(qs) //a=1&b=2&c=3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="GetInternalIp">GetInternalIp</span>
|
||||
<p>Get internal ip information.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func GetInternalIp() string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
internalIp := netutil.GetInternalIp()
|
||||
ip := net.ParseIP(internalIp)
|
||||
|
||||
fmt.Println(ip) //192.168.1.9
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="GetIps">GetIps</span>
|
||||
<p>Get all ipv4 list.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func GetIps() []string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ips := netutil.GetIps()
|
||||
fmt.Println(ips) //[192.168.1.9]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="GetMacAddrs">GetMacAddrs</span>
|
||||
<p>Get all mac addresses list.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func GetMacAddrs() []string {
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
addrs := netutil.GetMacAddrs()
|
||||
fmt.Println(addrs)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="GetPublicIpInfo">GetPublicIpInfo</span>
|
||||
<p>Get public ip information.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func GetPublicIpInfo() (*PublicIpInfo, error)
|
||||
type PublicIpInfo struct {
|
||||
Status string `json:"status"`
|
||||
Country string `json:"country"`
|
||||
CountryCode string `json:"countryCode"`
|
||||
Region string `json:"region"`
|
||||
RegionName string `json:"regionName"`
|
||||
City string `json:"city"`
|
||||
Lat float64 `json:"lat"`
|
||||
Lon float64 `json:"lon"`
|
||||
Isp string `json:"isp"`
|
||||
Org string `json:"org"`
|
||||
As string `json:"as"`
|
||||
Ip string `json:"query"`
|
||||
}
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
publicIpInfo, err := netutil.GetPublicIpInfo()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
fmt.Println(publicIpInfo)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="IsPublicIP">IsPublicIP</span>
|
||||
<p>Checks if a ip is public or not.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsPublicIP(IP net.IP) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ip1 := net.ParseIP("192.168.0.1")
|
||||
ip2 := net.ParseIP("36.112.24.10")
|
||||
|
||||
fmt.Println(netutil.IsPublicIP(ip1)) //false
|
||||
fmt.Println(netutil.IsPublicIP(ip2)) //true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="HttpGet">HttpGet</span>
|
||||
<p>Send http get request.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
// params[0] is header which type should be http.Header or map[string]string,
|
||||
// params[1] is query param which type should be url.Values or map[string]any,
|
||||
// params[2] is post body which type should be []byte.
|
||||
// params[3] is http client which type should be http.Client.
|
||||
func HttpGet(url string, params ...any) (*http.Response, error)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
url := "https://jsonplaceholder.typicode.com/todos/1"
|
||||
header := map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
|
||||
resp, err := netutil.HttpGet(url, header)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
fmt.Println(body)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="HttpPost">HttpPost</span>
|
||||
<p>Send http post request.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
// params[0] is header which type should be http.Header or map[string]string,
|
||||
// params[1] is query param which type should be url.Values or map[string]any,
|
||||
// params[2] is post body which type should be []byte.
|
||||
// params[3] is http client which type should be http.Client.
|
||||
func HttpPost(url string, params ...any) (*http.Response, error)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
url := "https://jsonplaceholder.typicode.com/todos"
|
||||
header := map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
type Todo struct {
|
||||
UserId int `json:"userId"`
|
||||
Title string `json:"title"`
|
||||
}
|
||||
todo := Todo{1, "TestAddToDo"}
|
||||
bodyParams, _ := json.Marshal(todo)
|
||||
|
||||
resp, err := netutil.HttpPost(url, header, nil, bodyParams)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
fmt.Println(body)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="HttpPut">HttpPut</span>
|
||||
<p>Send http put request.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
// params[0] is header which type should be http.Header or map[string]string,
|
||||
// params[1] is query param which type should be url.Values or map[string]any,
|
||||
// params[2] is post body which type should be []byte.
|
||||
// params[3] is http client which type should be http.Client.
|
||||
func HttpPut(url string, params ...any) (*http.Response, error)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
url := "https://jsonplaceholder.typicode.com/todos/1"
|
||||
header := map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
type Todo struct {
|
||||
Id int `json:"id"`
|
||||
UserId int `json:"userId"`
|
||||
Title string `json:"title"`
|
||||
}
|
||||
todo := Todo{1, 1, "TestPutToDo"}
|
||||
bodyParams, _ := json.Marshal(todo)
|
||||
|
||||
resp, err := netutil.HttpPut(url, header, nil, bodyParams)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
fmt.Println(body)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="HttpDelete">HttpDelete</span>
|
||||
<p>Send http delete request.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
// params[0] is header which type should be http.Header or map[string]string,
|
||||
// params[1] is query param which type should be url.Values or map[string]any,
|
||||
// params[2] is post body which type should be []byte.
|
||||
// params[3] is http client which type should be http.Client.
|
||||
func HttpDelete(url string, params ...any) (*http.Response, error)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
url := "https://jsonplaceholder.typicode.com/todos/1"
|
||||
resp, err := netutil.HttpDelete(url)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
fmt.Println(body)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="HttpPatch">HttpPatch</span>
|
||||
<p>Send http patch request.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
// params[0] is header which type should be http.Header or map[string]string,
|
||||
// params[1] is query param which type should be url.Values or map[string]any,
|
||||
// params[2] is post body which type should be []byte.
|
||||
// params[3] is http client which type should be http.Client.
|
||||
func HttpPatch(url string, params ...any) (*http.Response, error)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
url := "https://jsonplaceholder.typicode.com/todos/1"
|
||||
header := map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
type Todo struct {
|
||||
Id int `json:"id"`
|
||||
UserId int `json:"userId"`
|
||||
Title string `json:"title"`
|
||||
}
|
||||
todo := Todo{1, 1, "TestPatchToDo"}
|
||||
bodyParams, _ := json.Marshal(todo)
|
||||
|
||||
resp, err := netutil.HttpPatch(url, header, nil, bodyParams)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
fmt.Println(body)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ParseHttpResponse">ParseHttpResponse</span>
|
||||
<p>Decode http response to specified interface.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ParseHttpResponse(resp *http.Response, obj any) error
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
url := "https://jsonplaceholder.typicode.com/todos/1"
|
||||
header := map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
|
||||
resp, err := netutil.HttpGet(url, header)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
type Todo struct {
|
||||
Id int `json:"id"`
|
||||
UserId int `json:"userId"`
|
||||
Title string `json:"title"`
|
||||
Completed bool `json:"completed"`
|
||||
}
|
||||
|
||||
toDoResp := &Todo{}
|
||||
err = netutil.ParseHttpResponse(resp, toDoResp)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println(toDoResp)
|
||||
}
|
||||
```
|
||||
|
||||
509
docs/netutil_zh-CN.md
Normal file
509
docs/netutil_zh-CN.md
Normal file
@@ -0,0 +1,509 @@
|
||||
# Netutil
|
||||
netutil网络包支持获取ip地址,发送http请求。
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/netutil/net.go](https://github.com/duke-git/lancet/blob/main/netutil/net.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/netutil/http.go](https://github.com/duke-git/lancet/blob/main/netutil/http.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录
|
||||
- [ConvertMapToQueryString](#ConvertMapToQueryString)
|
||||
- [GetInternalIp](#GetInternalIp)
|
||||
- [GetIps](#GetIps)
|
||||
- [GetMacAddrs](#GetMacAddrs)
|
||||
- [GetPublicIpInfo](#GetPublicIpInfo)
|
||||
- [IsPublicIP](#IsPublicIP)
|
||||
- [HttpGet](#HttpGet)
|
||||
- [HttpDelete](#HttpDelete)
|
||||
- [HttpPost](#HttpPost)
|
||||
- [HttpPut](#HttpPut)
|
||||
|
||||
- [HttpPatch](#HttpPatch)
|
||||
- [ParseHttpResponse](#ParseHttpResponse)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 文档
|
||||
|
||||
|
||||
### <span id="ConvertMapToQueryString">ConvertMapToQueryString</span>
|
||||
<p>将map转换成http查询字符串.</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ConvertMapToQueryString(param map[string]any) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var m = map[string]any{
|
||||
"c": 3,
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
}
|
||||
qs := netutil.ConvertMapToQueryString(m)
|
||||
|
||||
fmt.Println(qs) //a=1&b=2&c=3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="GetInternalIp">GetInternalIp</span>
|
||||
<p>获取内部ip</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func GetInternalIp() string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
internalIp := netutil.GetInternalIp()
|
||||
ip := net.ParseIP(internalIp)
|
||||
|
||||
fmt.Println(ip) //192.168.1.9
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="GetIps">GetIps</span>
|
||||
<p>获取ipv4地址列表</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func GetIps() []string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ips := netutil.GetIps()
|
||||
fmt.Println(ips) //[192.168.1.9]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="GetMacAddrs">GetMacAddrs</span>
|
||||
<p>获取mac地址列</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func GetMacAddrs() []string {
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
addrs := netutil.GetMacAddrs()
|
||||
fmt.Println(addrs)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="GetPublicIpInfo">GetPublicIpInfo</span>
|
||||
<p>获取公网ip信息</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func GetPublicIpInfo() (*PublicIpInfo, error)
|
||||
type PublicIpInfo struct {
|
||||
Status string `json:"status"`
|
||||
Country string `json:"country"`
|
||||
CountryCode string `json:"countryCode"`
|
||||
Region string `json:"region"`
|
||||
RegionName string `json:"regionName"`
|
||||
City string `json:"city"`
|
||||
Lat float64 `json:"lat"`
|
||||
Lon float64 `json:"lon"`
|
||||
Isp string `json:"isp"`
|
||||
Org string `json:"org"`
|
||||
As string `json:"as"`
|
||||
Ip string `json:"query"`
|
||||
}
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
publicIpInfo, err := netutil.GetPublicIpInfo()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
fmt.Println(publicIpInfo)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="IsPublicIP">IsPublicIP</span>
|
||||
<p>判断ip是否是公共ip</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsPublicIP(IP net.IP) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ip1 := net.ParseIP("192.168.0.1")
|
||||
ip2 := net.ParseIP("36.112.24.10")
|
||||
|
||||
fmt.Println(netutil.IsPublicIP(ip1)) //false
|
||||
fmt.Println(netutil.IsPublicIP(ip2)) //true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="HttpGet">HttpGet</span>
|
||||
<p>发送http get请求</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
// params[0] http请求header,类型必须是http.Header或者map[string]string
|
||||
// params[1] http查询字符串,类型必须是url.Values或者map[string]any
|
||||
// params[2] post请求体,类型必须是[]byte
|
||||
// params[3] http client,类型必须是http.Client
|
||||
func HttpGet(url string, params ...any) (*http.Response, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
url := "https://jsonplaceholder.typicode.com/todos/1"
|
||||
header := map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
|
||||
resp, err := netutil.HttpGet(url, header)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
fmt.Println(body)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="HttpPost">HttpPost</span>
|
||||
<p>发送http post请求</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
// params[0] http请求header,类型必须是http.Header或者map[string]string
|
||||
// params[1] http查询字符串,类型必须是url.Values或者map[string]any
|
||||
// params[2] post请求体,类型必须是[]byte
|
||||
// params[3] http client,类型必须是http.Client
|
||||
func HttpPost(url string, params ...any) (*http.Response, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
url := "https://jsonplaceholder.typicode.com/todos"
|
||||
header := map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
type Todo struct {
|
||||
UserId int `json:"userId"`
|
||||
Title string `json:"title"`
|
||||
}
|
||||
todo := Todo{1, "TestAddToDo"}
|
||||
bodyParams, _ := json.Marshal(todo)
|
||||
|
||||
resp, err := netutil.HttpPost(url, header, nil, bodyParams)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
fmt.Println(body)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="HttpPut">HttpPut</span>
|
||||
<p>发送http put请求</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
// params[0] http请求header,类型必须是http.Header或者map[string]string
|
||||
// params[1] http查询字符串,类型必须是url.Values或者map[string]any
|
||||
// params[2] post请求体,类型必须是[]byte
|
||||
// params[3] http client,类型必须是http.Client
|
||||
func HttpPut(url string, params ...any) (*http.Response, error)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
url := "https://jsonplaceholder.typicode.com/todos/1"
|
||||
header := map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
type Todo struct {
|
||||
Id int `json:"id"`
|
||||
UserId int `json:"userId"`
|
||||
Title string `json:"title"`
|
||||
}
|
||||
todo := Todo{1, 1, "TestPutToDo"}
|
||||
bodyParams, _ := json.Marshal(todo)
|
||||
|
||||
resp, err := netutil.HttpPut(url, header, nil, bodyParams)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
fmt.Println(body)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="HttpDelete">HttpDelete</span>
|
||||
<p>发送http delete请求</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
// params[0] http请求header,类型必须是http.Header或者map[string]string
|
||||
// params[1] http查询字符串,类型必须是url.Values或者map[string]any
|
||||
// params[2] post请求体,类型必须是[]byte
|
||||
// params[3] http client,类型必须是http.Client
|
||||
func HttpDelete(url string, params ...any) (*http.Response, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
url := "https://jsonplaceholder.typicode.com/todos/1"
|
||||
resp, err := netutil.HttpDelete(url)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
fmt.Println(body)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="HttpPatch">HttpPatch</span>
|
||||
<p>发送http patch请求</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
// params[0] http请求header,类型必须是http.Header或者map[string]string
|
||||
// params[1] http查询字符串,类型必须是url.Values或者map[string]any
|
||||
// params[2] post请求体,类型必须是[]byte
|
||||
// params[3] http client,类型必须是http.Client
|
||||
func HttpPatch(url string, params ...any) (*http.Response, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
url := "https://jsonplaceholder.typicode.com/todos/1"
|
||||
header := map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
type Todo struct {
|
||||
Id int `json:"id"`
|
||||
UserId int `json:"userId"`
|
||||
Title string `json:"title"`
|
||||
}
|
||||
todo := Todo{1, 1, "TestPatchToDo"}
|
||||
bodyParams, _ := json.Marshal(todo)
|
||||
|
||||
resp, err := netutil.HttpPatch(url, header, nil, bodyParams)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
fmt.Println(body)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ParseHttpResponse">ParseHttpResponse</span>
|
||||
<p>将http请求响应解码成特定struct值</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ParseHttpResponse(resp *http.Response, obj any) error
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/v2/netutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
url := "https://jsonplaceholder.typicode.com/todos/1"
|
||||
header := map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
|
||||
resp, err := netutil.HttpGet(url, header)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
type Todo struct {
|
||||
Id int `json:"id"`
|
||||
UserId int `json:"userId"`
|
||||
Title string `json:"title"`
|
||||
Completed bool `json:"completed"`
|
||||
}
|
||||
|
||||
toDoResp := &Todo{}
|
||||
err = netutil.ParseHttpResponse(resp, toDoResp)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println(toDoResp)
|
||||
}
|
||||
```
|
||||
|
||||
138
docs/random.md
Normal file
138
docs/random.md
Normal file
@@ -0,0 +1,138 @@
|
||||
# Random
|
||||
Package random implements some basic functions to generate random int and string.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/random/random.go](https://github.com/duke-git/lancet/blob/main/random/random.go)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Usage:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/random"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [RandBytes](#RandBytes)
|
||||
- [RandInt](#RandInt)
|
||||
- [RandString](#RandString)
|
||||
- [UUIdV4](#UUIdV4)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
### <span id="RandBytes">RandBytes</span>
|
||||
<p>Generate random byte slice.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func RandBytes(length int) []byte
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/random"
|
||||
)
|
||||
|
||||
func main() {
|
||||
randBytes := random.RandBytes(4)
|
||||
fmt.Println(randBytes)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="RandInt">RandInt</span>
|
||||
<p>Generate random int between min and max, may contain min, not max.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func RandInt(min, max int) int
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/random"
|
||||
)
|
||||
|
||||
func main() {
|
||||
rInt := random.RandInt(1, 10)
|
||||
fmt.Println(rInt)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="RandString">RandInt</span>
|
||||
<p>Generate random given length string.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func RandString(length int) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/random"
|
||||
)
|
||||
|
||||
func main() {
|
||||
randStr := random.RandString(6)
|
||||
fmt.Println(randStr)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="UUIdV4">UUIdV4</span>
|
||||
<p>Generate a random UUID of version 4 according to RFC 4122.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func UUIdV4() (string, error)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/random"
|
||||
)
|
||||
|
||||
func main() {
|
||||
uuid, err := random.UUIdV4()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
fmt.Println(uuid)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
138
docs/random_zh-CN.md
Normal file
138
docs/random_zh-CN.md
Normal file
@@ -0,0 +1,138 @@
|
||||
# Random
|
||||
random随机数生成器包,可以生成随机[]bytes, int, string。
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/random/random.go](https://github.com/duke-git/lancet/blob/main/random/random.go)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/random"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录
|
||||
- [RandBytes](#RandBytes)
|
||||
- [RandInt](#RandInt)
|
||||
- [RandString](#RandString)
|
||||
- [UUIdV4](#UUIdV4)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 文档
|
||||
|
||||
|
||||
### <span id="RandBytes">RandBytes</span>
|
||||
<p>生成随机字节切片</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func RandBytes(length int) []byte
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/random"
|
||||
)
|
||||
|
||||
func main() {
|
||||
randBytes := random.RandBytes(4)
|
||||
fmt.Println(randBytes)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="RandInt">RandInt</span>
|
||||
<p>生成随机int, 范围[min, max)</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func RandInt(min, max int) int
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/random"
|
||||
)
|
||||
|
||||
func main() {
|
||||
rInt := random.RandInt(1, 10)
|
||||
fmt.Println(rInt)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="RandString">RandInt</span>
|
||||
<p>生成随机给定长度的随机字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func RandString(length int) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/random"
|
||||
)
|
||||
|
||||
func main() {
|
||||
randStr := random.RandString(6)
|
||||
fmt.Println(randStr)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="UUIdV4">UUIdV4</span>
|
||||
<p>生成UUID v4字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func UUIdV4() (string, error)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/random"
|
||||
)
|
||||
|
||||
func main() {
|
||||
uuid, err := random.UUIdV4()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
fmt.Println(uuid)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
236
docs/retry.md
Normal file
236
docs/retry.md
Normal file
@@ -0,0 +1,236 @@
|
||||
# Retry
|
||||
Package retry is for executing a function repeatedly until it was successful or canceled by the context.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/retry/retry.go](https://github.com/duke-git/lancet/blob/main/retry/retry.go)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Usage:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/retry"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [Context](#Context)
|
||||
- [Retry](#Retry)
|
||||
- [RetryFunc](#RetryFunc)
|
||||
- [RetryDuration](#RetryDuration)
|
||||
- [RetryTimes](#RetryTimes)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
### <span id="Context">Context</span>
|
||||
<p>Set retry context config, can cancel the retry with context.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Context(ctx context.Context)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/retry"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, cancel := context.WithCancel(context.TODO())
|
||||
var number int
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number > 3 {
|
||||
cancel()
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
err := retry.Retry(increaseNumber,
|
||||
retry.RetryDuration(time.Microsecond*50),
|
||||
retry.Context(ctx),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err) //retry is cancelled
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="RetryFunc">RetryFunc</span>
|
||||
<p>Function that retry executes.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
type RetryFunc func() error
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/v2/retry"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var number int
|
||||
var increaseNumber retry.RetryFunc
|
||||
increaseNumber = func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println(number) //3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="RetryTimes">RetryTimes</span>
|
||||
<p>Set times of retry. Default times is 5.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func RetryTimes(n uint)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/v2/retry"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var number int
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
err := retry.Retry(increaseNumber, retry.RetryTimes(2))
|
||||
if err != nil {
|
||||
log.Fatal(err) //2022/02/01 18:42:25 function main.main.func1 run failed after 2 times retry exit status 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="RetryDuration">RetryDuration</span>
|
||||
<p>Set duration of retries. Default duration is 3 second.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func RetryDuration(d time.Duration)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/v2/retry"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var number int
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println(number) //3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="Retry">Retry</span>
|
||||
<p>Executes the retryFunc repeatedly until it was successful or canceled by the context.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Retry(retryFunc RetryFunc, opts ...Option) error
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/v2/retry"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var number int
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println(number) //3
|
||||
}
|
||||
```
|
||||
238
docs/retry_zh-CN.md
Normal file
238
docs/retry_zh-CN.md
Normal file
@@ -0,0 +1,238 @@
|
||||
# Retry
|
||||
retry重试执行函数直到函数运行成功或被context cancel。
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/retry/retry.go](https://github.com/duke-git/lancet/blob/main/retry/retry.go)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/retry"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录
|
||||
- [Context](#Context)
|
||||
- [Retry](#Retry)
|
||||
- [RetryFunc](#RetryFunc)
|
||||
- [RetryDuration](#RetryDuration)
|
||||
- [RetryTimes](#RetryTimes)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
|
||||
## Document文档
|
||||
|
||||
|
||||
### <span id="Context">Context</span>
|
||||
<p>设置重试context参数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Context(ctx context.Context)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"lancet-demo/retry"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, cancel := context.WithCancel(context.TODO())
|
||||
var number int
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number > 3 {
|
||||
cancel()
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
err := retry.Retry(increaseNumber,
|
||||
retry.RetryDuration(time.Microsecond*50),
|
||||
retry.Context(ctx),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err) //retry is cancelled
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="RetryFunc">RetryFunc</span>
|
||||
<p>被重试执行的函数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
type RetryFunc func() error
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/v2/retry"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var number int
|
||||
var increaseNumber retry.RetryFunc
|
||||
increaseNumber = func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println(number) //3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="RetryTimes">RetryTimes</span>
|
||||
<p>设置重试次数,默认5</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func RetryTimes(n uint)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/v2/retry"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var number int
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
err := retry.Retry(increaseNumber, retry.RetryTimes(2))
|
||||
if err != nil {
|
||||
log.Fatal(err) //2022/02/01 18:42:25 function main.main.func1 run failed after 2 times retry exit status 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="RetryDuration">RetryDuration</span>
|
||||
<p>设置重试间隔时间,默认3秒</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func RetryDuration(d time.Duration)
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/v2/retry"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var number int
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println(number) //3
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="Retry">Retry</span>
|
||||
<p>重试执行函数retryFunc,直到函数运行成功,或被context停止</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Retry(retryFunc RetryFunc, opts ...Option) error
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/v2/retry"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var number int
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println(number) //3
|
||||
}
|
||||
```
|
||||
1021
docs/slice.md
Normal file
1021
docs/slice.md
Normal file
File diff suppressed because it is too large
Load Diff
1021
docs/slice_zh-CN.md
Normal file
1021
docs/slice_zh-CN.md
Normal file
File diff suppressed because it is too large
Load Diff
574
docs/strutil.md
Normal file
574
docs/strutil.md
Normal file
@@ -0,0 +1,574 @@
|
||||
# Strutil
|
||||
Package strutil contains some functions to manipulate string.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/strutil/string.go](https://github.com/duke-git/lancet/blob/main/strutil/string.go)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Usage:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [After](#After)
|
||||
- [AfterLast](#AfterLast)
|
||||
- [Before](#Before)
|
||||
- [BeforeLast](#BeforeLast)
|
||||
- [CamelCase](#CamelCase)
|
||||
- [Capitalize](#Capitalize)
|
||||
- [IsString](#IsString)
|
||||
- [KebabCase](#KebabCase)
|
||||
- [LowerFirst](#LowerFirst)
|
||||
- [UpperFirst](#UpperFirst)
|
||||
- [PadEnd](#PadEnd)
|
||||
- [PadStart](#PadStart)
|
||||
- [ReverseStr](#ReverseStr)
|
||||
- [SnakeCase](#SnakeCase)
|
||||
- [Wrap](#Wrap)
|
||||
|
||||
- [Unwrap](#Unwrap)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
### <span id="After">After</span>
|
||||
<p>Creates substring in source string after position when char first appear.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func After(s, char string) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.After("lancet", "")
|
||||
fmt.Println(s1) //lancet
|
||||
|
||||
s2 := strutil.After("github.com/test/lancet", "/")
|
||||
fmt.Println(s2) //test/lancet
|
||||
|
||||
s3 := strutil.After("github.com/test/lancet", "test")
|
||||
fmt.Println(s3) // /lancet
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="AfterLast">AfterLast</span>
|
||||
<p>Creates substring in source string after position when char last appear.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func AfterLast(s, char string) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.AfterLast("lancet", "")
|
||||
fmt.Println(s1) //lancet
|
||||
|
||||
s2 := strutil.AfterLast("github.com/test/lancet", "/")
|
||||
fmt.Println(s2) //lancet
|
||||
|
||||
s3 := strutil.AfterLast("github.com/test/test/lancet", "test")
|
||||
fmt.Println(s3) // /test/lancet
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="Before">Before</span>
|
||||
<p>Creates substring in source string before position when char first appear.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Before(s, char string) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.Before("lancet", "")
|
||||
fmt.Println(s1) //lancet
|
||||
|
||||
s2 := strutil.Before("github.com/test/lancet", "/")
|
||||
fmt.Println(s2) //github.com
|
||||
|
||||
s3 := strutil.Before("github.com/test/lancet", "test")
|
||||
fmt.Println(s3) // github.com/
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="BeforeLast">BeforeLast</span>
|
||||
<p>Creates substring in source string before position when char first appear.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func BeforeLast(s, char string) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.BeforeLast("lancet", "")
|
||||
fmt.Println(s1) //lancet
|
||||
|
||||
s2 := strutil.BeforeLast("github.com/test/lancet", "/")
|
||||
fmt.Println(s2) //github.com/test
|
||||
|
||||
s3 := strutil.BeforeLast("github.com/test/test/lancet", "test")
|
||||
fmt.Println(s3) //github.com/test/
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="CamelCase">CamelCase</span>
|
||||
<p>Covert string to camelCase string.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func CamelCase(s string) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.CamelCase("foo_bar")
|
||||
fmt.Println(s1) //fooBar
|
||||
|
||||
s2 := strutil.CamelCase("Foo-Bar")
|
||||
fmt.Println(s2) //fooBar
|
||||
|
||||
s3 := strutil.CamelCase("Foo&bar")
|
||||
fmt.Println(s3) //fooBar
|
||||
|
||||
s4 := strutil.CamelCase("foo bar")
|
||||
fmt.Println(s4) //fooBar
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="Capitalize">Capitalize</span>
|
||||
<p>Convert the first character of a string to upper case.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Capitalize(s string) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.Capitalize("foo")
|
||||
fmt.Println(s1) //foo
|
||||
|
||||
s2 := strutil.Capitalize("Foo")
|
||||
fmt.Println(s2) //foo
|
||||
|
||||
s3 := strutil.Capitalize("FOo"
|
||||
fmt.Println(s3) //fOo
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="IsString">IsString</span>
|
||||
<p>Check if the value's data type is string.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsString(v any) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(strutil.IsString("lancet")) //true
|
||||
fmt.Println(strutil.IsString("")) //true
|
||||
|
||||
fmt.Println(strutil.IsString(1)) //false
|
||||
fmt.Println(strutil.IsString("")) //false
|
||||
fmt.Println(strutil.IsString([]string{})) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="KebabCase">KebabCase</span>
|
||||
<p>Covert string to kebab-case.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func KebabCase(s string) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.KebabCase("Foo Bar-")
|
||||
fmt.Println(s1) //foo-bar
|
||||
|
||||
s2 := strutil.KebabCase("foo_Bar")
|
||||
fmt.Println(s2) //foo-bar
|
||||
|
||||
s3 := strutil.KebabCase("fooBar")
|
||||
fmt.Println(s3) //foo-bar
|
||||
|
||||
s4 := strutil.KebabCase("__FOO_BAR__")
|
||||
fmt.Println(s4) //f-o-o-b-a-r
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="LowerFirst">LowerFirst</span>
|
||||
<p>Convert the first character of string to lower case.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func LowerFirst(s string) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.LowerFirst("foo")
|
||||
fmt.Println(s1) //foo
|
||||
|
||||
s2 := strutil.LowerFirst("BAR")
|
||||
fmt.Println(s2) //bAR
|
||||
|
||||
s3 := strutil.LowerFirst("FOo")
|
||||
fmt.Println(s3) //fOo
|
||||
|
||||
s4 := strutil.LowerFirst("fOo大")
|
||||
fmt.Println(s4) //fOo大
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="UpperFirst">UpperFirst</span>
|
||||
<p>Convert the first character of string to upper case.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func UpperFirst(s string) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.UpperFirst("foo")
|
||||
fmt.Println(s1) //Foo
|
||||
|
||||
s2 := strutil.UpperFirst("bAR")
|
||||
fmt.Println(s2) //BAR
|
||||
|
||||
s3 := strutil.UpperFirst("FOo")
|
||||
fmt.Println(s3) //FOo
|
||||
|
||||
s4 := strutil.UpperFirst("fOo大")
|
||||
fmt.Println(s4) //FOo大
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="PadEnd">PadEnd</span>
|
||||
<p>Pads string on the right side if it's shorter than size.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func PadEnd(source string, size int, padStr string) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.PadEnd("a", 1, "b")
|
||||
fmt.Println(s1) //a
|
||||
|
||||
s2 := strutil.PadEnd("a", 2, "b")
|
||||
fmt.Println(s2) //ab
|
||||
|
||||
s3 := strutil.PadEnd("abcd", 6, "mno")
|
||||
fmt.Println(s3) //abcdmn
|
||||
|
||||
s4 := strutil.PadEnd("abc", 6, "ab")
|
||||
fmt.Println(s4) //abcaba
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="PadStart">PadStart</span>
|
||||
<p>Pads string on the left side if it's shorter than size.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func PadStart(source string, size int, padStr string) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.PadStart("a", 1, "b")
|
||||
fmt.Println(s1) //a
|
||||
|
||||
s2 := strutil.PadStart("a", 2, "b")
|
||||
fmt.Println(s2) //ba
|
||||
|
||||
s3 := strutil.PadStart("abcd", 6, "mno")
|
||||
fmt.Println(s3) //mnabcd
|
||||
|
||||
s4 := strutil.PadStart("abc", 6, "ab")
|
||||
fmt.Println(s4) //abaabc
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="ReverseStr">ReverseStr</span>
|
||||
<p>Return string whose char order is reversed to the given string.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ReverseStr(s string) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.ReverseStr("abc")
|
||||
fmt.Println(s1) //cba
|
||||
|
||||
s2 := strutil.ReverseStr("12345")
|
||||
fmt.Println(s2) //54321
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="SnakeCase">SnakeCase</span>
|
||||
<p>Covert string to snake_case.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func SnakeCase(s string) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.SnakeCase("Foo Bar-")
|
||||
fmt.Println(s1) //foo_bar
|
||||
|
||||
s2 := strutil.SnakeCase("foo_Bar")
|
||||
fmt.Println(s2) //foo_bar
|
||||
|
||||
s3 := strutil.SnakeCase("fooBar")
|
||||
fmt.Println(s3) //foo_bar
|
||||
|
||||
s4 := strutil.SnakeCase("__FOO_BAR__")
|
||||
fmt.Println(s4) //f_o_o_b_a_r
|
||||
|
||||
s5 := strutil.SnakeCase("aBbc-s$@a&%_B.B^C")
|
||||
fmt.Println(s5) //a_bbc_s_a_b_b_c
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="Wrap">Wrap</span>
|
||||
<p>Wrap a string with another string.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Wrap(str string, wrapWith string) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.Wrap("ab", "")
|
||||
fmt.Println(s1) //ab
|
||||
|
||||
s2 := strutil.Wrap("", "*")
|
||||
fmt.Println(s2) //""
|
||||
|
||||
s3 := strutil.Wrap("ab", "*")
|
||||
fmt.Println(s3) //*ab*
|
||||
|
||||
s4 := strutil.Wrap("ab", "\"")
|
||||
fmt.Println(s4) //\"ab\"
|
||||
|
||||
s5 := strutil.Wrap("ab", "'")
|
||||
fmt.Println(s5) //'ab'
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="Wrap">Wrap</span>
|
||||
<p>Unwrap a given string from anther string. will change str value.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Unwrap(str string, wrapToken string) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.Unwrap("ab", "")
|
||||
fmt.Println(s1) //ab
|
||||
|
||||
s2 := strutil.Unwrap("ab", "*")
|
||||
fmt.Println(s2) //ab
|
||||
|
||||
s3 := strutil.Unwrap("**ab**", "*")
|
||||
fmt.Println(s3) //*ab*
|
||||
|
||||
s4 := strutil.Unwrap("*ab", "*")
|
||||
fmt.Println(s4) //*ab
|
||||
|
||||
s5 := strutil.Unwrap("***", "**")
|
||||
fmt.Println(s5) //***
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
575
docs/strutil_zh-CN.md
Normal file
575
docs/strutil_zh-CN.md
Normal file
@@ -0,0 +1,575 @@
|
||||
# Strutil
|
||||
strutil包含处理字符串的相关函数。
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/strutil/string.go](https://github.com/duke-git/lancet/blob/main/strutil/string.go)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录
|
||||
- [After](#After)
|
||||
- [AfterLast](#AfterLast)
|
||||
- [Before](#Before)
|
||||
- [BeforeLast](#BeforeLast)
|
||||
- [CamelCase](#CamelCase)
|
||||
- [Capitalize](#Capitalize)
|
||||
- [IsString](#IsString)
|
||||
- [KebabCase](#KebabCase)
|
||||
- [LowerFirst](#LowerFirst)
|
||||
- [UpperFirst](#UpperFirst)
|
||||
- [PadEnd](#PadEnd)
|
||||
- [PadStart](#PadStart)
|
||||
- [ReverseStr](#ReverseStr)
|
||||
- [SnakeCase](#SnakeCase)
|
||||
- [Wrap](#Wrap)
|
||||
|
||||
- [Unwrap](#Unwrap)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
|
||||
## Documentation文档
|
||||
|
||||
|
||||
### <span id="After">After</span>
|
||||
<p>截取源字符串中char首次出现时的位置之后的子字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func After(s, char string) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.After("lancet", "")
|
||||
fmt.Println(s1) //lancet
|
||||
|
||||
s2 := strutil.After("github.com/test/lancet", "/")
|
||||
fmt.Println(s2) //test/lancet
|
||||
|
||||
s3 := strutil.After("github.com/test/lancet", "test")
|
||||
fmt.Println(s3) // /lancet
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="AfterLast">AfterLast</span>
|
||||
<p>截取源字符串中char最后一次出现时的位置之后的子字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func AfterLast(s, char string) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.AfterLast("lancet", "")
|
||||
fmt.Println(s1) //lancet
|
||||
|
||||
s2 := strutil.AfterLast("github.com/test/lancet", "/")
|
||||
fmt.Println(s2) //lancet
|
||||
|
||||
s3 := strutil.AfterLast("github.com/test/test/lancet", "test")
|
||||
fmt.Println(s3) // /lancet
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="Before">Before</span>
|
||||
<p>截取源字符串中char首次出现时的位置之前的子字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Before(s, char string) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.Before("lancet", "")
|
||||
fmt.Println(s1) //lancet
|
||||
|
||||
s2 := strutil.Before("github.com/test/lancet", "/")
|
||||
fmt.Println(s2) //github.com
|
||||
|
||||
s3 := strutil.Before("github.com/test/lancet", "test")
|
||||
fmt.Println(s3) // github.com/
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="BeforeLast">BeforeLast</span>
|
||||
<p>截取源字符串中char最后一次出现时的位置之前的子字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func BeforeLast(s, char string) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.BeforeLast("lancet", "")
|
||||
fmt.Println(s1) //lancet
|
||||
|
||||
s2 := strutil.BeforeLast("github.com/test/lancet", "/")
|
||||
fmt.Println(s2) //github.com/test
|
||||
|
||||
s3 := strutil.BeforeLast("github.com/test/test/lancet", "test")
|
||||
fmt.Println(s3) //github.com/test/
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="CamelCase">CamelCase</span>
|
||||
<p>将字符串转换为驼峰式字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func CamelCase(s string) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.CamelCase("foo_bar")
|
||||
fmt.Println(s1) //fooBar
|
||||
|
||||
s2 := strutil.CamelCase("Foo-Bar")
|
||||
fmt.Println(s2) //fooBar
|
||||
|
||||
s3 := strutil.CamelCase("Foo&bar")
|
||||
fmt.Println(s3) //fooBar
|
||||
|
||||
s4 := strutil.CamelCase("foo bar")
|
||||
fmt.Println(s4) //fooBar
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="Capitalize">Capitalize</span>
|
||||
<p>将字符串的第一个字符转换为大写</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Capitalize(s string) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.Capitalize("foo")
|
||||
fmt.Println(s1) //foo
|
||||
|
||||
s2 := strutil.Capitalize("Foo")
|
||||
fmt.Println(s2) //foo
|
||||
|
||||
s3 := strutil.Capitalize("FOo"
|
||||
fmt.Println(s3) //fOo
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="IsString">IsString</span>
|
||||
<p>检查值的数据类型是否为字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsString(v any) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(strutil.IsString("lancet")) //true
|
||||
fmt.Println(strutil.IsString("")) //true
|
||||
|
||||
fmt.Println(strutil.IsString(1)) //false
|
||||
fmt.Println(strutil.IsString("")) //false
|
||||
fmt.Println(strutil.IsString([]string{})) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="KebabCase">KebabCase</span>
|
||||
<p>将字符串转换为kebab-case</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func KebabCase(s string) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.KebabCase("Foo Bar-")
|
||||
fmt.Println(s1) //foo-bar
|
||||
|
||||
s2 := strutil.KebabCase("foo_Bar")
|
||||
fmt.Println(s2) //foo-bar
|
||||
|
||||
s3 := strutil.KebabCase("fooBar")
|
||||
fmt.Println(s3) //foo-bar
|
||||
|
||||
s4 := strutil.KebabCase("__FOO_BAR__")
|
||||
fmt.Println(s4) //f-o-o-b-a-r
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="LowerFirst">LowerFirst</span>
|
||||
<p>将字符串的第一个字符转换为小写</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func LowerFirst(s string) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.LowerFirst("foo")
|
||||
fmt.Println(s1) //foo
|
||||
|
||||
s2 := strutil.LowerFirst("BAR")
|
||||
fmt.Println(s2) //bAR
|
||||
|
||||
s3 := strutil.LowerFirst("FOo")
|
||||
fmt.Println(s3) //fOo
|
||||
|
||||
s4 := strutil.LowerFirst("fOo大")
|
||||
fmt.Println(s4) //fOo大
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="UpperFirst">UpperFirst</span>
|
||||
<p>将字符串的第一个字符转换为大写</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func UpperFirst(s string) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.UpperFirst("foo")
|
||||
fmt.Println(s1) //Foo
|
||||
|
||||
s2 := strutil.UpperFirst("bAR")
|
||||
fmt.Println(s2) //BAR
|
||||
|
||||
s3 := strutil.UpperFirst("FOo")
|
||||
fmt.Println(s3) //FOo
|
||||
|
||||
s4 := strutil.UpperFirst("fOo大")
|
||||
fmt.Println(s4) //FOo大
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="PadEnd">PadEnd</span>
|
||||
<p>如果字符串长度短于size,则在右侧填充字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func PadEnd(source string, size int, padStr string) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.PadEnd("a", 1, "b")
|
||||
fmt.Println(s1) //a
|
||||
|
||||
s2 := strutil.PadEnd("a", 2, "b")
|
||||
fmt.Println(s2) //ab
|
||||
|
||||
s3 := strutil.PadEnd("abcd", 6, "mno")
|
||||
fmt.Println(s3) //abcdmn
|
||||
|
||||
s4 := strutil.PadEnd("abc", 6, "ab")
|
||||
fmt.Println(s4) //abcaba
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="PadStart">PadStart</span>
|
||||
<p>如果字符串长度短于size,则在左侧填充字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func PadStart(source string, size int, padStr string) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.PadStart("a", 1, "b")
|
||||
fmt.Println(s1) //a
|
||||
|
||||
s2 := strutil.PadStart("a", 2, "b")
|
||||
fmt.Println(s2) //ba
|
||||
|
||||
s3 := strutil.PadStart("abcd", 6, "mno")
|
||||
fmt.Println(s3) //mnabcd
|
||||
|
||||
s4 := strutil.PadStart("abc", 6, "ab")
|
||||
fmt.Println(s4) //abaabc
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="ReverseStr">ReverseStr</span>
|
||||
<p>返回字符顺序与给定字符串相反的字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ReverseStr(s string) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.ReverseStr("abc")
|
||||
fmt.Println(s1) //cba
|
||||
|
||||
s2 := strutil.ReverseStr("12345")
|
||||
fmt.Println(s2) //54321
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="SnakeCase">SnakeCase</span>
|
||||
<p>将字符串转换为snake_case形式</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func SnakeCase(s string) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.SnakeCase("Foo Bar-")
|
||||
fmt.Println(s1) //foo_bar
|
||||
|
||||
s2 := strutil.SnakeCase("foo_Bar")
|
||||
fmt.Println(s2) //foo_bar
|
||||
|
||||
s3 := strutil.SnakeCase("fooBar")
|
||||
fmt.Println(s3) //foo_bar
|
||||
|
||||
s4 := strutil.SnakeCase("__FOO_BAR__")
|
||||
fmt.Println(s4) //f_o_o_b_a_r
|
||||
|
||||
s5 := strutil.SnakeCase("aBbc-s$@a&%_B.B^C")
|
||||
fmt.Println(s5) //a_bbc_s_a_b_b_c
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="Wrap">Wrap</span>
|
||||
<p>用另一个字符串包裹一个字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Wrap(str string, wrapWith string) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.Wrap("ab", "")
|
||||
fmt.Println(s1) //ab
|
||||
|
||||
s2 := strutil.Wrap("", "*")
|
||||
fmt.Println(s2) //""
|
||||
|
||||
s3 := strutil.Wrap("ab", "*")
|
||||
fmt.Println(s3) //*ab*
|
||||
|
||||
s4 := strutil.Wrap("ab", "\"")
|
||||
fmt.Println(s4) //\"ab\"
|
||||
|
||||
s5 := strutil.Wrap("ab", "'")
|
||||
fmt.Println(s5) //'ab'
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="Unwrap">Unwrap</span>
|
||||
<p>用另一个字符串解开包裹一个字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Unwrap(str string, wrapToken string) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.Unwrap("ab", "")
|
||||
fmt.Println(s1) //ab
|
||||
|
||||
s2 := strutil.Unwrap("ab", "*")
|
||||
fmt.Println(s2) //ab
|
||||
|
||||
s3 := strutil.Unwrap("**ab**", "*")
|
||||
fmt.Println(s3) //*ab*
|
||||
|
||||
s4 := strutil.Unwrap("*ab", "*")
|
||||
fmt.Println(s4) //*ab
|
||||
|
||||
s5 := strutil.Unwrap("***", "**")
|
||||
fmt.Println(s5) //***
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
242
docs/system.md
Normal file
242
docs/system.md
Normal file
@@ -0,0 +1,242 @@
|
||||
# System
|
||||
Package system contains some functions about os, runtime, shell command.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/system/os.go](https://github.com/duke-git/lancet/blob/main/system/os.go)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Usage:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [IsWindows](#IsWindows)
|
||||
- [IsLinux](#IsLinux)
|
||||
- [IsMac](#IsMac)
|
||||
- [GetOsEnv](#GetOsEnv)
|
||||
- [SetOsEnv](#SetOsEnv)
|
||||
- [RemoveOsEnv](#RemoveOsEnv)
|
||||
- [CompareOsEnv](#CompareOsEnv)
|
||||
- [ExecCommand](#ExecCommand)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
### <span id="IsWindows">IsWindows</span>
|
||||
<p>Check if current os is windows.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsWindows() bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
isOsWindows := system.IsWindows()
|
||||
fmt.Println(isOsWindows)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsLinux">IsLinux</span>
|
||||
<p>Check if current os is linux.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsLinux() bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
isOsLinux := system.IsLinux()
|
||||
fmt.Println(isOsLinux)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="IsMac">IsMac</span>
|
||||
<p>Check if current os is macos.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsMac() bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
isOsMac := system.IsMac
|
||||
fmt.Println(isOsMac)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="GetOsEnv">GetOsEnv</span>
|
||||
<p>Gets the value of the environment variable named by the key.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func GetOsEnv(key string) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fooEnv := system.GetOsEnv("foo")
|
||||
fmt.Println(fooEnv)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="SetOsEnv">SetOsEnv</span>
|
||||
<p>Sets the value of the environment variable named by the key.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func SetOsEnv(key, value string) error
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := system.SetOsEnv("foo", "foo_value")
|
||||
fmt.Println(err)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="RemoveOsEnv">RemoveOsEnv</span>
|
||||
<p>Remove a single environment variable.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func RemoveOsEnv(key string) error
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := system.RemoveOsEnv("foo")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="CompareOsEnv">CompareOsEnv</span>
|
||||
<p>Get env named by the key and compare it with comparedEnv.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func CompareOsEnv(key, comparedEnv string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
system.SetOsEnv("foo", "foo_value")
|
||||
res := system.CompareOsEnv("foo", "foo_value")
|
||||
fmt.Println(res) //true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="ExecCommand">CompareOsEnv</span>
|
||||
<p>use shell /bin/bash -c(linux) or cmd (windows) to execute command.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ExecCommand(command string) (stdout, stderr string, err error)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
out, errout, err := system.ExecCommand("ls")
|
||||
fmt.Println(out)
|
||||
fmt.Println(errout)
|
||||
fmt.Println(err)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
242
docs/system_zh-CN.md
Normal file
242
docs/system_zh-CN.md
Normal file
@@ -0,0 +1,242 @@
|
||||
# System
|
||||
system包含os, runtime, shell command相关函数。
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/system/os.go](https://github.com/duke-git/lancet/blob/main/system/os.go)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录
|
||||
- [IsWindows](#IsWindows)
|
||||
- [IsLinux](#IsLinux)
|
||||
- [IsMac](#IsMac)
|
||||
- [GetOsEnv](#GetOsEnv)
|
||||
- [SetOsEnv](#SetOsEnv)
|
||||
- [RemoveOsEnv](#RemoveOsEnv)
|
||||
- [CompareOsEnv](#CompareOsEnv)
|
||||
- [ExecCommand](#ExecCommand)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation文档
|
||||
|
||||
|
||||
### <span id="IsWindows">IsWindows</span>
|
||||
<p>检查当前操作系统是否是windows</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsWindows() bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
isOsWindows := system.IsWindows()
|
||||
fmt.Println(isOsWindows)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsLinux">IsLinux</span>
|
||||
<p>检查当前操作系统是否是linux</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsLinux() bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
isOsLinux := system.IsLinux()
|
||||
fmt.Println(isOsLinux)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="IsMac">IsMac</span>
|
||||
<p>检查当前操作系统是否是macos</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsMac() bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
isOsMac := system.IsMac
|
||||
fmt.Println(isOsMac)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="GetOsEnv">GetOsEnv</span>
|
||||
<p>获取key命名的环境变量的值</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func GetOsEnv(key string) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fooEnv := system.GetOsEnv("foo")
|
||||
fmt.Println(fooEnv)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="SetOsEnv">SetOsEnv</span>
|
||||
<p>设置由key命名的环境变量的值</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func SetOsEnv(key, value string) error
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := system.SetOsEnv("foo", "foo_value")
|
||||
fmt.Println(err)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="RemoveOsEnv">RemoveOsEnv</span>
|
||||
<p>删除单个环境变量</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func RemoveOsEnv(key string) error
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := system.RemoveOsEnv("foo")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="CompareOsEnv">CompareOsEnv</span>
|
||||
<p>获取key命名的环境变量值并与compareEnv进行比较</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func CompareOsEnv(key, comparedEnv string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
system.SetOsEnv("foo", "foo_value")
|
||||
res := system.CompareOsEnv("foo", "foo_value")
|
||||
fmt.Println(res) //true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="ExecCommand">CompareOsEnv</span>
|
||||
<p>使用shell /bin/bash -c(linux) 或 cmd (windows) 执行shell命令</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ExecCommand(command string) (stdout, stderr string, err error)
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/system"
|
||||
)
|
||||
|
||||
func main() {
|
||||
out, errout, err := system.ExecCommand("ls")
|
||||
fmt.Println(out)
|
||||
fmt.Println(errout)
|
||||
fmt.Println(err)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
799
docs/validator.md
Normal file
799
docs/validator.md
Normal file
@@ -0,0 +1,799 @@
|
||||
# Validator
|
||||
Package validator contains some functions for data validation.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/validator/validator.go](https://github.com/duke-git/lancet/blob/main/validator/validator.go)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Usage:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [ContainChinese](#ContainChinese)
|
||||
- [ContainLetter](#ContainLetter)
|
||||
- [ContainLower](#ContainLower)
|
||||
- [ContainUpper](#ContainUpper)
|
||||
- [IsAlpha](#IsAlpha)
|
||||
- [IsAllUpper](#IsAllUpper)
|
||||
- [IsAllLower](#IsAllLower)
|
||||
- [IsBase64](#IsBase64)
|
||||
- [IsChineseMobile](#IsChineseMobile)
|
||||
- [IsChineseIdNum](#IsChineseIdNum)
|
||||
- [IsChinesePhone](#IsChinesePhone)
|
||||
- [IsCreditCard](#IsCreditCard)
|
||||
- [IsDns](#IsDns)
|
||||
- [IsEmail](#IsEmail)
|
||||
|
||||
- [IsEmptyString](#IsEmptyString)
|
||||
- [IsFloatStr](#IsFloatStr)
|
||||
- [IsNumberStr](#IsNumberStr)
|
||||
- [IsJSON](#IsJSON)
|
||||
- [IsRegexMatch](#IsRegexMatch)
|
||||
- [IsIntStr](#IsIntStr)
|
||||
- [IsIp](#IsIp)
|
||||
- [IsIpV4](#IsIpV4)
|
||||
- [IsIpV6](#IsIpV6)
|
||||
- [IsStrongPassword](#IsStrongPassword)
|
||||
- [IsUrl](#IsUrl)
|
||||
- [IsWeakPassword](#IsWeakPassword)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
### <span id="ContainChinese">ContainChinese</span>
|
||||
<p>Check if the string contain mandarin chinese.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ContainChinese(s string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.ContainChinese("你好")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.ContainChinese("你好hello")
|
||||
fmt.Println(res2) //true
|
||||
|
||||
res3 := validator.ContainChinese("hello")
|
||||
fmt.Println(res3) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ContainLetter">ContainLetter</span>
|
||||
<p>Check if the string contain at least one letter.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ContainLetter(str string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.ContainLetter("1bc")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.ContainLetter("123")
|
||||
fmt.Println(res2) //false
|
||||
|
||||
res3 := validator.ContainLetter("&@#$%^&*")
|
||||
fmt.Println(res3) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="ContainLower">ContainLower</span>
|
||||
<p>Check if the string contain at least one lower case letter a-z.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ContainLower(str string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.ContainLower("1bc")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.ContainLower("123")
|
||||
fmt.Println(res2) //false
|
||||
|
||||
res3 := validator.ContainLower("1BC")
|
||||
fmt.Println(res3) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="ContainUpper">ContainUpper</span>
|
||||
<p>Check if the string contain at least one upper case letter A-Z.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ContainUpper(str string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.ContainUpper("1bc")
|
||||
fmt.Println(res1) //false
|
||||
|
||||
res2 := validator.ContainUpper("123")
|
||||
fmt.Println(res2) //false
|
||||
|
||||
res3 := validator.ContainUpper("1BC")
|
||||
fmt.Println(res3) //true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsAlpha">IsAlpha</span>
|
||||
<p>Check if the string contains only letters (a-zA-Z).</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsAlpha(s string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.IsAlpha("abc")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.IsAlpha("1bc")
|
||||
fmt.Println(res2) //false
|
||||
|
||||
res3 := validator.IsAlpha("")
|
||||
fmt.Println(res3) //false
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="IsAllUpper">IsAllUpper</span>
|
||||
<p>Check if string is all upper case letters A-Z.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsAllUpper(str string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.IsAllUpper("ABC")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.IsAllUpper("aBC")
|
||||
fmt.Println(res2) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsAllLower">IsAllLower</span>
|
||||
<p>Check if string is all lower case letters a-z.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsAllLower(str string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.IsAllLower("abc")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.IsAllLower("abC")
|
||||
fmt.Println(res2) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsBase64">IsBase64</span>
|
||||
<p>Check if the string is base64 string.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsBase64(base64 string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.IsBase64("aGVsbG8=")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.IsBase64("123456")
|
||||
fmt.Println(res2) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsChineseMobile">IsChineseMobile</span>
|
||||
<p>Check if the string is valid chinese mobile number.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsChineseMobile(mobileNum string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.IsChineseMobile("13263527980")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.IsChineseMobile("434324324")
|
||||
fmt.Println(res2) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="IsChineseIdNum">IsChineseIdNum</span>
|
||||
<p>Check if the string is chinese id number.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsChineseIdNum(id string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.IsChineseIdNum("210911192105130715")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.IsChineseIdNum("123456")
|
||||
fmt.Println(res2) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsChinesePhone">IsChinesePhone</span>
|
||||
<p>Check if the string is chinese phone number.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsChinesePhone(phone string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.IsChinesePhone("010-32116675")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.IsChinesePhone("123-87562")
|
||||
fmt.Println(res2) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsCreditCard">IsCreditCard</span>
|
||||
<p>Check if the string is credit card.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsCreditCard(creditCart string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.IsCreditCard("4111111111111111")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.IsCreditCard("123456")
|
||||
fmt.Println(res2) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsDns">IsDns</span>
|
||||
<p>Check if the string is valid dns.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsDns(dns string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.IsDns("abc.com")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.IsDns("a.b.com")
|
||||
fmt.Println(res2) //false
|
||||
|
||||
res3 := validator.IsDns("http://abc.com")
|
||||
fmt.Println(res3) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsEmail">IsEmail</span>
|
||||
<p>Check if the string is email address.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsEmail(email string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.IsEmail("abc@xyz.com")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.IsEmail("a.b@@com")
|
||||
fmt.Println(res2) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsEmptyString">IsEmptyString</span>
|
||||
<p>Check if the string is empty or not.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsEmptyString(s string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.IsEmptyString("")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.IsEmptyString("abc")
|
||||
fmt.Println(res2) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsFloatStr">IsFloatStr</span>
|
||||
<p>Check if the string can convert to a float.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsFloatStr(s string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(validator.IsFloatStr("")) //false
|
||||
fmt.Println(validator.IsFloatStr("12a")) //false
|
||||
fmt.Println(validator.IsFloatStr("3.")) //true
|
||||
fmt.Println(validator.IsFloatStr("+3.")) //true
|
||||
fmt.Println(validator.IsFloatStr("-3.")) //true
|
||||
fmt.Println(validator.IsFloatStr("12")) //true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsNumberStr">IsNumberStr</span>
|
||||
<p>Check if the string can convert to a number.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsNumberStr(s string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(validator.IsNumberStr("")) //false
|
||||
fmt.Println(validator.IsNumberStr("12a")) //false
|
||||
fmt.Println(validator.IsNumberStr("3.")) //true
|
||||
fmt.Println(validator.IsNumberStr("+3.")) //true
|
||||
fmt.Println(validator.IsNumberStr("-3.")) //true
|
||||
fmt.Println(validator.IsNumberStr("+3e2")) //true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsJSON">IsJSON</span>
|
||||
<p>Check if the string is valid JSON.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsJSON(str string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(validator.IsJSON("")) //false
|
||||
fmt.Println(validator.IsJSON("abc")) //false
|
||||
fmt.Println(validator.IsJSON("{}")) //true
|
||||
fmt.Println(validator.IsJSON("[]")) //true
|
||||
fmt.Println(validator.IsJSON("123")) //true
|
||||
fmt.Println(validator.IsJSON("{\"name\": \"test\"}")) //true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsRegexMatch">IsRegexMatch</span>
|
||||
<p>Check if the string match the regexp.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsRegexMatch(s, regex string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(validator.IsRegexMatch("abc", `^[a-zA-Z]+$`)) //true
|
||||
fmt.Println(validator.IsRegexMatch("1ab", `^[a-zA-Z]+$`)) //false
|
||||
fmt.Println(validator.IsRegexMatch("", `^[a-zA-Z]+$`)) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsIntStr">IsIntStr</span>
|
||||
<p>Check if the string can convert to a integer.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsIntStr(s string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(validator.IsIntStr("+3")) //true
|
||||
fmt.Println(validator.IsIntStr("-3")) //true
|
||||
fmt.Println(validator.IsIntStr("3.")) //false
|
||||
fmt.Println(validator.IsIntStr("abc")) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsIp">IsIp</span>
|
||||
<p>Check if the string is a ip address.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsIp(ipstr string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(validator.IsIp("127.0.0.1")) //true
|
||||
fmt.Println(validator.IsIp("::0:0:0:0:0:0:1")) //true
|
||||
fmt.Println(validator.IsIp("127.0.0")) //false
|
||||
fmt.Println(validator.IsIp("127")) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsIpV4">IsIpV4</span>
|
||||
<p>Check if the string is a ipv4 address.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsIpV4(ipstr string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(validator.IsIpV4("127.0.0.1")) //true
|
||||
fmt.Println(validator.IsIpV4("::0:0:0:0:0:0:1")) //false
|
||||
fmt.Println(validator.IsIpV4("127.0.0")) //false
|
||||
fmt.Println(validator.IsIpV4("127")) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsIpV6">IsIpV6</span>
|
||||
<p>Check if the string is a ipv6 address.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsIpV6(ipstr string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(validator.IsIpV6("127.0.0.1")) //false
|
||||
fmt.Println(validator.IsIpV6("::0:0:0:0:0:0:1")) //true
|
||||
fmt.Println(validator.IsIpV6("127.0.0")) //false
|
||||
fmt.Println(validator.IsIpV6("127")) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsStrongPassword">IsStrongPassword</span>
|
||||
<p>Check if the string is strong password (alpha(lower+upper) + number + special chars(!@#$%^&*()?><)).</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsStrongPassword(password string, length int) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(validator.IsStrongPassword("abc", 3)) //false
|
||||
fmt.Println(validator.IsStrongPassword("abc123", 6)) //false
|
||||
fmt.Println(validator.IsStrongPassword("abcABC", 6)) //false
|
||||
fmt.Println(validator.IsStrongPassword("abcABC123@#$", 16)) //false
|
||||
fmt.Println(validator.IsStrongPassword("abcABC123@#$", 12)) //true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsUrl">IsUrl</span>
|
||||
<p>Check if the string is url.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsUrl(str string) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(validator.IsUrl("http://abc.com")) //true
|
||||
fmt.Println(validator.IsUrl("abc.com")) //true
|
||||
fmt.Println(validator.IsUrl("a.b.com")) //true
|
||||
fmt.Println(validator.IsUrl("abc")) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsWeakPassword">IsWeakPassword</span>
|
||||
<p>Check if the string is weak password(only letter or only number or letter + number)
|
||||
.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsWeakPassword(password string, length int) bool
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(validator.IsWeakPassword("abc")) //true
|
||||
fmt.Println(validator.IsWeakPassword("123")) //true
|
||||
fmt.Println(validator.IsWeakPassword("abc123")) //true
|
||||
fmt.Println(validator.IsWeakPassword("abc123@#$")) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
799
docs/validator_zh-CN.md
Normal file
799
docs/validator_zh-CN.md
Normal file
@@ -0,0 +1,799 @@
|
||||
# Validator
|
||||
validator验证器包,包含常用字符串格式验证函数。
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/validator/validator.go](https://github.com/duke-git/lancet/blob/main/validator/validator.go)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录:
|
||||
- [ContainChinese](#ContainChinese)
|
||||
- [ContainLetter](#ContainLetter)
|
||||
- [ContainLower](#ContainLower)
|
||||
- [ContainUpper](#ContainUpper)
|
||||
- [IsAlpha](#IsAlpha)
|
||||
- [IsAllUpper](#IsAllUpper)
|
||||
- [IsAllLower](#IsAllLower)
|
||||
- [IsBase64](#IsBase64)
|
||||
- [IsChineseMobile](#IsChineseMobile)
|
||||
- [IsChineseIdNum](#IsChineseIdNum)
|
||||
- [IsChinesePhone](#IsChinesePhone)
|
||||
- [IsCreditCard](#IsCreditCard)
|
||||
- [IsDns](#IsDns)
|
||||
- [IsEmail](#IsEmail)
|
||||
|
||||
- [IsEmptyString](#IsEmptyString)
|
||||
- [IsFloatStr](#IsFloatStr)
|
||||
- [IsNumberStr](#IsNumberStr)
|
||||
- [IsJSON](#IsJSON)
|
||||
- [IsRegexMatch](#IsRegexMatch)
|
||||
- [IsIntStr](#IsIntStr)
|
||||
- [IsIp](#IsIp)
|
||||
- [IsIpV4](#IsIpV4)
|
||||
- [IsIpV6](#IsIpV6)
|
||||
- [IsStrongPassword](#IsStrongPassword)
|
||||
- [IsUrl](#IsUrl)
|
||||
- [IsWeakPassword](#IsWeakPassword)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 文档
|
||||
|
||||
|
||||
### <span id="ContainChinese">ContainChinese</span>
|
||||
<p>验证字符串是否包含中文字符</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ContainChinese(s string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.ContainChinese("你好")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.ContainChinese("你好hello")
|
||||
fmt.Println(res2) //true
|
||||
|
||||
res3 := validator.ContainChinese("hello")
|
||||
fmt.Println(res3) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="ContainLetter">ContainLetter</span>
|
||||
<p>验证字符串是否包含至少一个英文字母</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ContainLetter(str string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.ContainLetter("1bc")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.ContainLetter("123")
|
||||
fmt.Println(res2) //false
|
||||
|
||||
res3 := validator.ContainLetter("&@#$%^&*")
|
||||
fmt.Println(res3) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="ContainLower">ContainLower</span>
|
||||
<p>验证字符串是否包含至少一个英文小写字母</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ContainLower(str string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.ContainLower("1bc")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.ContainLower("123")
|
||||
fmt.Println(res2) //false
|
||||
|
||||
res3 := validator.ContainLower("1BC")
|
||||
fmt.Println(res3) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="ContainUpper">ContainUpper</span>
|
||||
<p>验证字符串是否包含至少一个英文大写字母.</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ContainUpper(str string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.ContainUpper("1bc")
|
||||
fmt.Println(res1) //false
|
||||
|
||||
res2 := validator.ContainUpper("123")
|
||||
fmt.Println(res2) //false
|
||||
|
||||
res3 := validator.ContainUpper("1BC")
|
||||
fmt.Println(res3) //true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsAlpha">IsAlpha</span>
|
||||
<p>验证字符串是否只包含英文字母</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsAlpha(s string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.IsAlpha("abc")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.IsAlpha("1bc")
|
||||
fmt.Println(res2) //false
|
||||
|
||||
res3 := validator.IsAlpha("")
|
||||
fmt.Println(res3) //false
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="IsAllUpper">IsAllUpper</span>
|
||||
<p>验证字符串是否全是大写英文字母</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsAllUpper(str string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.IsAllUpper("ABC")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.IsAllUpper("aBC")
|
||||
fmt.Println(res2) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsAllLower">IsAllLower</span>
|
||||
<p>验证字符串是否全是小写英文字母</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsAllLower(str string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.IsAllLower("abc")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.IsAllLower("abC")
|
||||
fmt.Println(res2) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsBase64">IsBase64</span>
|
||||
<p>验证字符串是否是base64编码</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsBase64(base64 string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.IsBase64("aGVsbG8=")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.IsBase64("123456")
|
||||
fmt.Println(res2) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsChineseMobile">IsChineseMobile</span>
|
||||
<p>验证字符串是否是中国手机号码</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsChineseMobile(mobileNum string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.IsChineseMobile("13263527980")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.IsChineseMobile("434324324")
|
||||
fmt.Println(res2) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="IsChineseIdNum">IsChineseIdNum</span>
|
||||
<p>验证字符串是否是中国身份证号码</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsChineseIdNum(id string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.IsChineseIdNum("210911192105130715")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.IsChineseIdNum("123456")
|
||||
fmt.Println(res2) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsChinesePhone">IsChinesePhone</span>
|
||||
<p>验证字符串是否是中国电话座机号码</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsChinesePhone(phone string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.IsChinesePhone("010-32116675")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.IsChinesePhone("123-87562")
|
||||
fmt.Println(res2) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsCreditCard">IsCreditCard</span>
|
||||
<p>验证字符串是否是信用卡号码</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsCreditCard(creditCart string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.IsCreditCard("4111111111111111")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.IsCreditCard("123456")
|
||||
fmt.Println(res2) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsDns">IsDns</span>
|
||||
<p>验证字符串是否是有效dns</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsDns(dns string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.IsDns("abc.com")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.IsDns("a.b.com")
|
||||
fmt.Println(res2) //false
|
||||
|
||||
res3 := validator.IsDns("http://abc.com")
|
||||
fmt.Println(res3) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsEmail">IsEmail</span>
|
||||
<p>验证字符串是否是有效电子邮件地址</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsEmail(email string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.IsEmail("abc@xyz.com")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.IsEmail("a.b@@com")
|
||||
fmt.Println(res2) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsEmptyString">IsEmptyString</span>
|
||||
<p>验证字符串是否是空字符串</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsEmptyString(s string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res1 := validator.IsEmptyString("")
|
||||
fmt.Println(res1) //true
|
||||
|
||||
res2 := validator.IsEmptyString("abc")
|
||||
fmt.Println(res2) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsFloatStr">IsFloatStr</span>
|
||||
<p>验证字符串是否是可以转换为浮点数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsFloatStr(s string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(validator.IsFloatStr("")) //false
|
||||
fmt.Println(validator.IsFloatStr("12a")) //false
|
||||
fmt.Println(validator.IsFloatStr("3.")) //true
|
||||
fmt.Println(validator.IsFloatStr("+3.")) //true
|
||||
fmt.Println(validator.IsFloatStr("-3.")) //true
|
||||
fmt.Println(validator.IsFloatStr("12")) //true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsNumberStr">IsNumberStr</span>
|
||||
<p>验证字符串是否是可以转换为数字</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsNumberStr(s string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(validator.IsNumberStr("")) //false
|
||||
fmt.Println(validator.IsNumberStr("12a")) //false
|
||||
fmt.Println(validator.IsNumberStr("3.")) //true
|
||||
fmt.Println(validator.IsNumberStr("+3.")) //true
|
||||
fmt.Println(validator.IsNumberStr("-3.")) //true
|
||||
fmt.Println(validator.IsNumberStr("+3e2")) //true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsJSON">IsJSON</span>
|
||||
<p>验证字符串是否是有效json</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsJSON(str string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(validator.IsJSON("")) //false
|
||||
fmt.Println(validator.IsJSON("abc")) //false
|
||||
fmt.Println(validator.IsJSON("{}")) //true
|
||||
fmt.Println(validator.IsJSON("[]")) //true
|
||||
fmt.Println(validator.IsJSON("123")) //true
|
||||
fmt.Println(validator.IsJSON("{\"name\": \"test\"}")) //true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsRegexMatch">IsRegexMatch</span>
|
||||
<p>验证字符串是否可以匹配正则表达式</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsRegexMatch(s, regex string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(validator.IsRegexMatch("abc", `^[a-zA-Z]+$`)) //true
|
||||
fmt.Println(validator.IsRegexMatch("1ab", `^[a-zA-Z]+$`)) //false
|
||||
fmt.Println(validator.IsRegexMatch("", `^[a-zA-Z]+$`)) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsIntStr">IsIntStr</span>
|
||||
<p>验证字符串是否是可以转换为整数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsIntStr(s string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(validator.IsIntStr("+3")) //true
|
||||
fmt.Println(validator.IsIntStr("-3")) //true
|
||||
fmt.Println(validator.IsIntStr("3.")) //false
|
||||
fmt.Println(validator.IsIntStr("abc")) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsIp">IsIp</span>
|
||||
<p>验证字符串是否是ip地址</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsIp(ipstr string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(validator.IsIp("127.0.0.1")) //true
|
||||
fmt.Println(validator.IsIp("::0:0:0:0:0:0:1")) //true
|
||||
fmt.Println(validator.IsIp("127.0.0")) //false
|
||||
fmt.Println(validator.IsIp("127")) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsIpV4">IsIpV4</span>
|
||||
<p>验证字符串是否是ipv4地址</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsIpV4(ipstr string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(validator.IsIpV4("127.0.0.1")) //true
|
||||
fmt.Println(validator.IsIpV4("::0:0:0:0:0:0:1")) //false
|
||||
fmt.Println(validator.IsIpV4("127.0.0")) //false
|
||||
fmt.Println(validator.IsIpV4("127")) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsIpV6">IsIpV6</span>
|
||||
<p>验证字符串是否是ipv6地址</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsIpV6(ipstr string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(validator.IsIpV6("127.0.0.1")) //false
|
||||
fmt.Println(validator.IsIpV6("::0:0:0:0:0:0:1")) //true
|
||||
fmt.Println(validator.IsIpV6("127.0.0")) //false
|
||||
fmt.Println(validator.IsIpV6("127")) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsStrongPassword">IsStrongPassword</span>
|
||||
<p>验证字符串是否是强密码:(alpha(lower+upper) + number + special chars(!@#$%^&*()?><))</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsStrongPassword(password string, length int) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(validator.IsStrongPassword("abc", 3)) //false
|
||||
fmt.Println(validator.IsStrongPassword("abc123", 6)) //false
|
||||
fmt.Println(validator.IsStrongPassword("abcABC", 6)) //false
|
||||
fmt.Println(validator.IsStrongPassword("abcABC123@#$", 16)) //false
|
||||
fmt.Println(validator.IsStrongPassword("abcABC123@#$", 12)) //true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsUrl">IsUrl</span>
|
||||
<p>验证字符串是否是url</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsUrl(str string) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(validator.IsUrl("http://abc.com")) //true
|
||||
fmt.Println(validator.IsUrl("abc.com")) //true
|
||||
fmt.Println(validator.IsUrl("a.b.com")) //true
|
||||
fmt.Println(validator.IsUrl("abc")) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="IsWeakPassword">IsWeakPassword</span>
|
||||
<p>验证字符串是否是弱密码:(only letter or only number or letter + number)
|
||||
.</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsWeakPassword(password string, length int) bool
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(validator.IsWeakPassword("abc")) //true
|
||||
fmt.Println(validator.IsWeakPassword("123")) //true
|
||||
fmt.Println(validator.IsWeakPassword("abc123")) //true
|
||||
fmt.Println(validator.IsWeakPassword("abc123@#$")) //false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
57
docs/xerror.md
Normal file
57
docs/xerror.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# Xerror
|
||||
Package xerror implements helpers for errors.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/xerror/xerror.go](https://github.com/duke-git/lancet/blob/main/xerror/xerror.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Usage:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/xerror"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [Unwrap](#Unwrap)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
|
||||
### <span id="Unwrap">Unwrap</span>
|
||||
<p>Unwrap if err is nil then it returns a valid value. If err is not nil, Unwrap panics with err.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Unwrap[T any](val T, err error) T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/xerror"
|
||||
)
|
||||
|
||||
func main() {
|
||||
_, err := strconv.Atoi("4o2")
|
||||
defer func() {
|
||||
v := recover()
|
||||
fmt.Println(err.Error()) // err.Error() == v.(*strconv.NumError).Error()
|
||||
}()
|
||||
|
||||
xerror.Unwrap(strconv.Atoi("4o2"))
|
||||
}
|
||||
```
|
||||
57
docs/xerror_zh-CN.md
Normal file
57
docs/xerror_zh-CN.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# Xerror
|
||||
xerror错误处理逻辑封装
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/xerror/xerror.go](https://github.com/duke-git/lancet/blob/main/xerror/xerror.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法:
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/v2/xerror"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录
|
||||
- [Unwrap](#Unwrap)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 文档
|
||||
|
||||
|
||||
|
||||
### <span id="Unwrap">Unwrap</span>
|
||||
<p>如果err为nil则展开,则它返回一个有效值。 如果err不是nil则Unwrap使用err发生恐慌。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Unwrap[T any](val T, err error) T
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/xerror"
|
||||
)
|
||||
|
||||
func main() {
|
||||
_, err := strconv.Atoi("4o2")
|
||||
defer func() {
|
||||
v := recover()
|
||||
fmt.Println(err.Error()) // err.Error() == v.(*strconv.NumError).Error()
|
||||
}()
|
||||
|
||||
xerror.Unwrap(strconv.Atoi("4o2"))
|
||||
}
|
||||
```
|
||||
@@ -263,7 +263,7 @@ func FileMode(path string) (fs.FileMode, error) {
|
||||
|
||||
// MiMeType return file mime type
|
||||
// param `file` should be string(file path) or *os.File
|
||||
func MiMeType(file interface{}) string {
|
||||
func MiMeType(file any) string {
|
||||
var mediatype string
|
||||
|
||||
readBuffer := func(f *os.File) ([]byte, error) {
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/internal"
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestIsExist(t *testing.T) {
|
||||
@@ -76,10 +76,10 @@ func TestCopyFile(t *testing.T) {
|
||||
func TestListFileNames(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestListFileNames")
|
||||
|
||||
filesInPath, err := ListFileNames("../datetime/")
|
||||
filesInPath, err := ListFileNames("./")
|
||||
assert.IsNil(err)
|
||||
|
||||
expected := []string{"datetime.go", "datetime_test.go"}
|
||||
expected := []string{"file.go", "file_test.go"}
|
||||
assert.Equal(expected, filesInPath)
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ package formatter
|
||||
import "strings"
|
||||
|
||||
// Comma add comma to number by every 3 numbers from right. ahead by symbol char
|
||||
func Comma(v interface{}, symbol string) string {
|
||||
func Comma(v any, symbol string) string {
|
||||
s := numString(v)
|
||||
dotIndex := strings.Index(s, ".")
|
||||
if dotIndex != -1 {
|
||||
|
||||
@@ -14,7 +14,7 @@ func commaString(s string) string {
|
||||
return commaString(s[:len(s)-3]) + "," + commaString(s[len(s)-3:])
|
||||
}
|
||||
|
||||
func numString(value interface{}) string {
|
||||
func numString(value any) string {
|
||||
switch reflect.TypeOf(value).Kind() {
|
||||
case reflect.Int, reflect.Int64, reflect.Float32, reflect.Float64:
|
||||
return fmt.Sprintf("%v", value)
|
||||
@@ -3,7 +3,7 @@ package formatter
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/internal"
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestComma(t *testing.T) {
|
||||
|
||||
@@ -10,10 +10,11 @@ import (
|
||||
)
|
||||
|
||||
// After creates a function that invokes func once it's called n or more times
|
||||
func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value {
|
||||
func After(n int, fn any) func(args ...any) []reflect.Value {
|
||||
// Catch programming error while constructing the closure
|
||||
mustBeFunction(fn)
|
||||
return func(args ...interface{}) []reflect.Value {
|
||||
|
||||
return func(args ...any) []reflect.Value {
|
||||
n--
|
||||
if n < 1 {
|
||||
return unsafeInvokeFunc(fn, args...)
|
||||
@@ -23,11 +24,11 @@ func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value {
|
||||
}
|
||||
|
||||
// Before creates a function that invokes func once it's called less than n times
|
||||
func Before(n int, fn interface{}) func(args ...interface{}) []reflect.Value {
|
||||
func Before(n int, fn any) func(args ...any) []reflect.Value {
|
||||
// Catch programming error while constructing the closure
|
||||
mustBeFunction(fn)
|
||||
var res []reflect.Value
|
||||
return func(args ...interface{}) []reflect.Value {
|
||||
return func(args ...any) []reflect.Value {
|
||||
if n > 0 {
|
||||
res = unsafeInvokeFunc(fn, args...)
|
||||
}
|
||||
@@ -39,20 +40,20 @@ func Before(n int, fn interface{}) func(args ...interface{}) []reflect.Value {
|
||||
}
|
||||
}
|
||||
|
||||
// Fn is for curry function which is func(...interface{}) interface{}
|
||||
type Fn func(...interface{}) interface{}
|
||||
// Fn is for curry function which is func(...any) any
|
||||
type Fn func(...any) any
|
||||
|
||||
// Curry make a curry function
|
||||
func (f Fn) Curry(i interface{}) func(...interface{}) interface{} {
|
||||
return func(values ...interface{}) interface{} {
|
||||
v := append([]interface{}{i}, values...)
|
||||
func (f Fn) Curry(i any) func(...any) any {
|
||||
return func(values ...any) any {
|
||||
v := append([]any{i}, values...)
|
||||
return f(v...)
|
||||
}
|
||||
}
|
||||
|
||||
// Compose compose the functions from right to left
|
||||
func Compose(fnList ...func(...interface{}) interface{}) func(...interface{}) interface{} {
|
||||
return func(s ...interface{}) interface{} {
|
||||
func Compose(fnList ...func(...any) any) func(...any) any {
|
||||
return func(s ...any) any {
|
||||
f := fnList[0]
|
||||
restFn := fnList[1:]
|
||||
|
||||
@@ -65,13 +66,19 @@ func Compose(fnList ...func(...interface{}) interface{}) func(...interface{}) in
|
||||
}
|
||||
|
||||
// Delay make the function execution after delayed time
|
||||
func Delay(delay time.Duration, fn interface{}, args ...interface{}) {
|
||||
func Delay(delay time.Duration, fn any, args ...any) {
|
||||
// Catch programming error while constructing the closure
|
||||
mustBeFunction(fn)
|
||||
|
||||
time.Sleep(delay)
|
||||
invokeFunc(fn, args...)
|
||||
}
|
||||
|
||||
// Debounced creates a debounced function that delays invoking fn until after wait duration have elapsed since the last time the debounced function was invoked.
|
||||
func Debounced(fn func(), duration time.Duration) func() {
|
||||
// Catch programming error while constructing the closure
|
||||
mustBeFunction(fn)
|
||||
|
||||
timer := time.NewTimer(duration)
|
||||
timer.Stop()
|
||||
|
||||
@@ -88,9 +95,10 @@ func Debounced(fn func(), duration time.Duration) func() {
|
||||
}
|
||||
|
||||
// Schedule invoke function every duration time, util close the returned bool chan
|
||||
func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool {
|
||||
func Schedule(d time.Duration, fn any, args ...any) chan bool {
|
||||
// Catch programming error while constructing the closure
|
||||
mustBeFunction(fn)
|
||||
|
||||
quit := make(chan bool)
|
||||
go func() {
|
||||
for {
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func invokeFunc(fn interface{}, args ...interface{}) []reflect.Value {
|
||||
func invokeFunc(fn any, args ...any) []reflect.Value {
|
||||
fv := functionValue(fn)
|
||||
params := make([]reflect.Value, len(args))
|
||||
for i, item := range args {
|
||||
@@ -14,7 +14,7 @@ func invokeFunc(fn interface{}, args ...interface{}) []reflect.Value {
|
||||
return fv.Call(params)
|
||||
}
|
||||
|
||||
func unsafeInvokeFunc(fn interface{}, args ...interface{}) []reflect.Value {
|
||||
func unsafeInvokeFunc(fn any, args ...any) []reflect.Value {
|
||||
fv := reflect.ValueOf(fn)
|
||||
params := make([]reflect.Value, len(args))
|
||||
for i, item := range args {
|
||||
@@ -23,7 +23,7 @@ func unsafeInvokeFunc(fn interface{}, args ...interface{}) []reflect.Value {
|
||||
return fv.Call(params)
|
||||
}
|
||||
|
||||
func functionValue(function interface{}) reflect.Value {
|
||||
func functionValue(function any) reflect.Value {
|
||||
v := reflect.ValueOf(function)
|
||||
if v.Kind() != reflect.Func {
|
||||
panic(fmt.Sprintf("Invalid function type, value of type %T", function))
|
||||
@@ -31,7 +31,7 @@ func functionValue(function interface{}) reflect.Value {
|
||||
return v
|
||||
}
|
||||
|
||||
func mustBeFunction(function interface{}) {
|
||||
func mustBeFunction(function any) {
|
||||
v := reflect.ValueOf(function)
|
||||
if v.Kind() != reflect.Func {
|
||||
panic(fmt.Sprintf("Invalid function type, value of type %T", function))
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/duke-git/lancet/internal"
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestAfter(t *testing.T) {
|
||||
@@ -16,7 +16,7 @@ func TestAfter(t *testing.T) {
|
||||
fmt.Println("print done")
|
||||
return i
|
||||
})
|
||||
type cb func(args ...interface{}) []reflect.Value
|
||||
type cb func(args ...any) []reflect.Value
|
||||
print := func(i int, s string, fn cb) {
|
||||
fmt.Printf("print: arr[%d] is %s \n", i, s)
|
||||
v := fn(i)
|
||||
@@ -42,7 +42,7 @@ func TestBefore(t *testing.T) {
|
||||
})
|
||||
|
||||
var res []int64
|
||||
type cb func(args ...interface{}) []reflect.Value
|
||||
type cb func(args ...any) []reflect.Value
|
||||
appendStr := func(i int, s string, fn cb) {
|
||||
v := fn(i)
|
||||
res = append(res, v[0].Int())
|
||||
@@ -62,7 +62,7 @@ func TestCurry(t *testing.T) {
|
||||
add := func(a, b int) int {
|
||||
return a + b
|
||||
}
|
||||
var addCurry Fn = func(values ...interface{}) interface{} {
|
||||
var addCurry Fn = func(values ...any) any {
|
||||
return add(values[0].(int), values[1].(int))
|
||||
}
|
||||
add1 := addCurry.Curry(1)
|
||||
@@ -72,10 +72,10 @@ func TestCurry(t *testing.T) {
|
||||
func TestCompose(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestCompose")
|
||||
|
||||
toUpper := func(a ...interface{}) interface{} {
|
||||
toUpper := func(a ...any) any {
|
||||
return strings.ToUpper(a[0].(string))
|
||||
}
|
||||
toLower := func(a ...interface{}) interface{} {
|
||||
toLower := func(a ...any) any {
|
||||
return strings.ToLower(a[0].(string))
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package function
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/internal"
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestWatcher(t *testing.T) {
|
||||
|
||||
4
go.mod
4
go.mod
@@ -1,3 +1,3 @@
|
||||
module github.com/duke-git/lancet
|
||||
module github.com/duke-git/lancet/v2
|
||||
|
||||
go 1.16
|
||||
go 1.18
|
||||
|
||||
@@ -30,14 +30,14 @@ func NewAssert(t *testing.T, caseName string) *Assert {
|
||||
}
|
||||
|
||||
// Equal check if expected is equal with actual
|
||||
func (a *Assert) Equal(expected, actual interface{}) {
|
||||
func (a *Assert) Equal(expected, actual any) {
|
||||
if compare(expected, actual) != compareEqual {
|
||||
makeTestFailed(a.T, a.CaseName, expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
// NotEqual check if expected is not equal with actual
|
||||
func (a *Assert) NotEqual(expected, actual interface{}) {
|
||||
func (a *Assert) NotEqual(expected, actual any) {
|
||||
if compare(expected, actual) == compareEqual {
|
||||
expectedInfo := fmt.Sprintf("not %v", expected)
|
||||
makeTestFailed(a.T, a.CaseName, expectedInfo, actual)
|
||||
@@ -45,7 +45,7 @@ func (a *Assert) NotEqual(expected, actual interface{}) {
|
||||
}
|
||||
|
||||
// Greater check if expected is greate than actual
|
||||
func (a *Assert) Greater(expected, actual interface{}) {
|
||||
func (a *Assert) Greater(expected, actual any) {
|
||||
if compare(expected, actual) != compareGreater {
|
||||
expectedInfo := fmt.Sprintf("> %v", expected)
|
||||
makeTestFailed(a.T, a.CaseName, expectedInfo, actual)
|
||||
@@ -53,7 +53,7 @@ func (a *Assert) Greater(expected, actual interface{}) {
|
||||
}
|
||||
|
||||
// GreaterOrEqual check if expected is greate than or equal with actual
|
||||
func (a *Assert) GreaterOrEqual(expected, actual interface{}) {
|
||||
func (a *Assert) GreaterOrEqual(expected, actual any) {
|
||||
isGreatOrEqual := compare(expected, actual) == compareGreater || compare(expected, actual) == compareEqual
|
||||
if !isGreatOrEqual {
|
||||
expectedInfo := fmt.Sprintf(">= %v", expected)
|
||||
@@ -62,7 +62,7 @@ func (a *Assert) GreaterOrEqual(expected, actual interface{}) {
|
||||
}
|
||||
|
||||
// Less check if expected is less than actual
|
||||
func (a *Assert) Less(expected, actual interface{}) {
|
||||
func (a *Assert) Less(expected, actual any) {
|
||||
if compare(expected, actual) != compareLess {
|
||||
expectedInfo := fmt.Sprintf("< %v", expected)
|
||||
makeTestFailed(a.T, a.CaseName, expectedInfo, actual)
|
||||
@@ -70,7 +70,7 @@ func (a *Assert) Less(expected, actual interface{}) {
|
||||
}
|
||||
|
||||
// LessOrEqual check if expected is less than or equal with actual
|
||||
func (a *Assert) LessOrEqual(expected, actual interface{}) {
|
||||
func (a *Assert) LessOrEqual(expected, actual any) {
|
||||
isLessOrEqual := compare(expected, actual) == compareLess || compare(expected, actual) == compareEqual
|
||||
if !isLessOrEqual {
|
||||
expectedInfo := fmt.Sprintf("<= %v", expected)
|
||||
@@ -79,14 +79,14 @@ func (a *Assert) LessOrEqual(expected, actual interface{}) {
|
||||
}
|
||||
|
||||
// IsNil check if value is nil
|
||||
func (a *Assert) IsNil(value interface{}) {
|
||||
func (a *Assert) IsNil(value any) {
|
||||
if value != nil {
|
||||
makeTestFailed(a.T, a.CaseName, nil, value)
|
||||
}
|
||||
}
|
||||
|
||||
// IsNotNil check if value is not nil
|
||||
func (a *Assert) IsNotNil(value interface{}) {
|
||||
func (a *Assert) IsNotNil(value any) {
|
||||
if value == nil {
|
||||
makeTestFailed(a.T, a.CaseName, "not nil", value)
|
||||
}
|
||||
@@ -94,7 +94,7 @@ func (a *Assert) IsNotNil(value interface{}) {
|
||||
|
||||
// compare x and y return :
|
||||
// x > y -> 1, x < y -> -1, x == y -> 0, x != y -> -2
|
||||
func compare(x, y interface{}) int {
|
||||
func compare(x, y any) int {
|
||||
vx := reflect.ValueOf(x)
|
||||
vy := reflect.ValueOf(y)
|
||||
|
||||
@@ -163,7 +163,7 @@ func compare(x, y interface{}) int {
|
||||
}
|
||||
|
||||
// logFailedInfo make test failed and log error info
|
||||
func makeTestFailed(t *testing.T, caseName string, expected, actual interface{}) {
|
||||
func makeTestFailed(t *testing.T, caseName string, expected, actual any) {
|
||||
_, file, line, _ := runtime.Caller(2)
|
||||
errInfo := fmt.Sprintf("Case %v failed. file: %v, line: %v, expected: %v, actual: %v.", caseName, file, line, expected, actual)
|
||||
t.Error(errInfo)
|
||||
|
||||
18
lancetconstraints/constraints.go
Normal file
18
lancetconstraints/constraints.go
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
|
||||
// Use of this source code is governed by MIT license
|
||||
|
||||
// Package lancetconstraints contain some comstomer constraints.
|
||||
package lancetconstraints
|
||||
|
||||
// Comparator is for comparing two values
|
||||
type Comparator interface {
|
||||
// Compare v1 and v2
|
||||
// Ascending order: should return 1 -> v1 > v2, 0 -> v1 = v2, -1 -> v1 < v2
|
||||
// Descending order: should return 1 -> v1 < v2, 0 -> v1 = v2, -1 -> v1 > v2
|
||||
Compare(v1, v2 any) int
|
||||
}
|
||||
|
||||
// Number contains all types of number and uintptr, used for generics constraint
|
||||
type Number interface {
|
||||
int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 | uintptr | float32 | float64
|
||||
}
|
||||
131
mathutil/mathutil.go
Normal file
131
mathutil/mathutil.go
Normal file
@@ -0,0 +1,131 @@
|
||||
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
|
||||
// Use of this source code is governed by MIT license
|
||||
|
||||
// Package mathutil implements some functions for math calculation.
|
||||
package mathutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/duke-git/lancet/v2/lancetconstraints"
|
||||
)
|
||||
|
||||
// Exponent calculate x^n
|
||||
func Exponent(x, n int64) int64 {
|
||||
if n == 0 {
|
||||
return 1
|
||||
}
|
||||
|
||||
t := Exponent(x, n/2)
|
||||
|
||||
if n%2 == 1 {
|
||||
return t * t * x
|
||||
}
|
||||
|
||||
return t * t
|
||||
}
|
||||
|
||||
// Fibonacci calculate fibonacci number before n
|
||||
func Fibonacci(first, second, n int) int {
|
||||
if n <= 0 {
|
||||
return 0
|
||||
}
|
||||
if n < 3 {
|
||||
return 1
|
||||
} else if n == 3 {
|
||||
return first + second
|
||||
} else {
|
||||
return Fibonacci(second, first+second, n-1)
|
||||
}
|
||||
}
|
||||
|
||||
// Factorial calculate x!
|
||||
func Factorial(x uint) uint {
|
||||
var f uint = 1
|
||||
for ; x > 1; x-- {
|
||||
f *= x
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
// Percent calculate the percentage of val to total
|
||||
func Percent(val, total float64, n int) float64 {
|
||||
if total == 0 {
|
||||
return float64(0)
|
||||
}
|
||||
tmp := val / total * 100
|
||||
res := RoundToFloat(tmp, n)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// RoundToString round up to n decimal places
|
||||
func RoundToString(x float64, n int) string {
|
||||
tmp := math.Pow(10.0, float64(n))
|
||||
x *= tmp
|
||||
x = math.Round(x)
|
||||
res := strconv.FormatFloat(x/tmp, 'f', n, 64)
|
||||
return res
|
||||
}
|
||||
|
||||
// RoundToFloat round up to n decimal places
|
||||
func RoundToFloat(x float64, n int) float64 {
|
||||
tmp := math.Pow(10.0, float64(n))
|
||||
x *= tmp
|
||||
x = math.Round(x)
|
||||
return x / tmp
|
||||
}
|
||||
|
||||
// TruncRound round off n decimal places
|
||||
func TruncRound(x float64, n int) float64 {
|
||||
floatStr := fmt.Sprintf("%."+strconv.Itoa(n+1)+"f", x)
|
||||
temp := strings.Split(floatStr, ".")
|
||||
var newFloat string
|
||||
if len(temp) < 2 || n >= len(temp[1]) {
|
||||
newFloat = floatStr
|
||||
} else {
|
||||
newFloat = temp[0] + "." + temp[1][:n]
|
||||
}
|
||||
res, _ := strconv.ParseFloat(newFloat, 64)
|
||||
return res
|
||||
}
|
||||
|
||||
// Max return max value of params
|
||||
func Max[T lancetconstraints.Number](numbers ...T) T {
|
||||
max := numbers[0]
|
||||
|
||||
for _, v := range numbers {
|
||||
if max < v {
|
||||
max = v
|
||||
}
|
||||
}
|
||||
|
||||
return max
|
||||
}
|
||||
|
||||
// Min return min value of params
|
||||
func Min[T lancetconstraints.Number](numbers ...T) T {
|
||||
min := numbers[0]
|
||||
|
||||
for _, v := range numbers {
|
||||
if min > v {
|
||||
min = v
|
||||
}
|
||||
}
|
||||
|
||||
return min
|
||||
}
|
||||
|
||||
// Average return average value of params
|
||||
func Average[T lancetconstraints.Number](numbers ...T) T {
|
||||
var sum T
|
||||
n := T(len(numbers))
|
||||
|
||||
for _, v := range numbers {
|
||||
sum += v
|
||||
}
|
||||
return sum / n
|
||||
}
|
||||
98
mathutil/mathutil_test.go
Normal file
98
mathutil/mathutil_test.go
Normal file
@@ -0,0 +1,98 @@
|
||||
package mathutil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestExponent(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestExponent")
|
||||
|
||||
assert.Equal(int64(1), Exponent(10, 0))
|
||||
assert.Equal(int64(10), Exponent(10, 1))
|
||||
assert.Equal(int64(100), Exponent(10, 2))
|
||||
}
|
||||
|
||||
func TestFibonacci(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestFibonacci")
|
||||
|
||||
assert.Equal(0, Fibonacci(1, 1, 0))
|
||||
assert.Equal(1, Fibonacci(1, 1, 1))
|
||||
assert.Equal(1, Fibonacci(1, 1, 2))
|
||||
assert.Equal(5, Fibonacci(1, 1, 5))
|
||||
}
|
||||
|
||||
func TestFactorial(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestFactorial")
|
||||
|
||||
assert.Equal(uint(1), Factorial(0))
|
||||
assert.Equal(uint(1), Factorial(1))
|
||||
assert.Equal(uint(2), Factorial(2))
|
||||
assert.Equal(uint(6), Factorial(3))
|
||||
}
|
||||
|
||||
func TestPercent(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestPercent")
|
||||
|
||||
assert.Equal(float64(50), Percent(1, 2, 2))
|
||||
assert.Equal(float64(33.33), Percent(0.1, 0.3, 2))
|
||||
}
|
||||
|
||||
func TestRoundToFloat(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestRoundToFloat")
|
||||
|
||||
assert.Equal(RoundToFloat(0, 0), float64(0))
|
||||
assert.Equal(RoundToFloat(0, 1), float64(0))
|
||||
assert.Equal(RoundToFloat(0.124, 2), float64(0.12))
|
||||
assert.Equal(RoundToFloat(0.125, 2), float64(0.13))
|
||||
assert.Equal(RoundToFloat(0.125, 3), float64(0.125))
|
||||
assert.Equal(RoundToFloat(33.33333, 2), float64(33.33))
|
||||
}
|
||||
|
||||
func TestRoundToString(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestRoundToString")
|
||||
|
||||
assert.Equal(RoundToString(0, 0), "0")
|
||||
assert.Equal(RoundToString(0, 1), "0.0")
|
||||
assert.Equal(RoundToString(0.124, 2), "0.12")
|
||||
assert.Equal(RoundToString(0.125, 2), "0.13")
|
||||
assert.Equal(RoundToString(0.125, 3), "0.125")
|
||||
}
|
||||
|
||||
func TestTruncRound(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestTruncRound")
|
||||
|
||||
assert.Equal(TruncRound(0, 0), float64(0))
|
||||
assert.Equal(TruncRound(0, 1), float64(0))
|
||||
assert.Equal(TruncRound(0.124, 2), float64(0.12))
|
||||
assert.Equal(TruncRound(0.125, 2), float64(0.12))
|
||||
assert.Equal(TruncRound(0.125, 3), float64(0.125))
|
||||
assert.Equal(TruncRound(33.33333, 2), float64(33.33))
|
||||
}
|
||||
|
||||
func TestAverage(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestAverage")
|
||||
|
||||
assert.Equal(Average(0, 0), 0)
|
||||
assert.Equal(Average(1, 1), 1)
|
||||
avg := Average(1.2, 1.4)
|
||||
t.Log(avg)
|
||||
assert.Equal(1.3, RoundToFloat(avg, 1))
|
||||
}
|
||||
|
||||
func TestMax(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestMax")
|
||||
|
||||
assert.Equal(Max(0, 0), 0)
|
||||
assert.Equal(Max(1, 2, 3), 3)
|
||||
assert.Equal(Max(1.2, 1.4, 1.1, 1.4), 1.4)
|
||||
}
|
||||
|
||||
func TestMin(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestMin")
|
||||
|
||||
assert.Equal(Min(0, 0), 0)
|
||||
assert.Equal(Min(1, 2, 3), 1)
|
||||
assert.Equal(Min(1.2, 1.4, 1.1, 1.4), 1.1)
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
// HttpGet, HttpPost, HttpDelete, HttpPut, HttpPatch, function param `url` is required.
|
||||
// HttpGet, HttpPost, HttpDelete, HttpPut, HttpPatch, function param `params` is variable, the order is:
|
||||
// params[0] is header which type should be http.Header or map[string]string,
|
||||
// params[1] is query param which type should be url.Values or map[string]interface{},
|
||||
// params[1] is query param which type should be url.Values or map[string]any,
|
||||
// params[2] is post body which type should be []byte.
|
||||
// params[3] is http client which type should be http.Client.
|
||||
package netutil
|
||||
@@ -21,32 +21,32 @@ import (
|
||||
)
|
||||
|
||||
//HttpGet send get http request
|
||||
func HttpGet(url string, params ...interface{}) (*http.Response, error) {
|
||||
func HttpGet(url string, params ...any) (*http.Response, error) {
|
||||
return doHttpRequest(http.MethodGet, url, params...)
|
||||
}
|
||||
|
||||
//HttpPost send post http request
|
||||
func HttpPost(url string, params ...interface{}) (*http.Response, error) {
|
||||
func HttpPost(url string, params ...any) (*http.Response, error) {
|
||||
return doHttpRequest(http.MethodPost, url, params...)
|
||||
}
|
||||
|
||||
//HttpPut send put http request
|
||||
func HttpPut(url string, params ...interface{}) (*http.Response, error) {
|
||||
func HttpPut(url string, params ...any) (*http.Response, error) {
|
||||
return doHttpRequest(http.MethodPut, url, params...)
|
||||
}
|
||||
|
||||
//HttpDelete send delete http request
|
||||
func HttpDelete(url string, params ...interface{}) (*http.Response, error) {
|
||||
func HttpDelete(url string, params ...any) (*http.Response, error) {
|
||||
return doHttpRequest(http.MethodDelete, url, params...)
|
||||
}
|
||||
|
||||
// HttpPatch send patch http request
|
||||
func HttpPatch(url string, params ...interface{}) (*http.Response, error) {
|
||||
func HttpPatch(url string, params ...any) (*http.Response, error) {
|
||||
return doHttpRequest(http.MethodPatch, url, params...)
|
||||
}
|
||||
|
||||
// ParseHttpResponse decode http response to specified interface
|
||||
func ParseHttpResponse(resp *http.Response, obj interface{}) error {
|
||||
func ParseHttpResponse(resp *http.Response, obj any) error {
|
||||
if resp == nil {
|
||||
return errors.New("InvalidResp")
|
||||
}
|
||||
@@ -55,7 +55,7 @@ func ParseHttpResponse(resp *http.Response, obj interface{}) error {
|
||||
}
|
||||
|
||||
// ConvertMapToQueryString convert map to sorted url query string
|
||||
func ConvertMapToQueryString(param map[string]interface{}) string {
|
||||
func ConvertMapToQueryString(param map[string]any) string {
|
||||
if param == nil {
|
||||
return ""
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"log"
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/internal"
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestHttpGet(t *testing.T) {
|
||||
@@ -104,7 +104,7 @@ func TestHttpDelete(t *testing.T) {
|
||||
func TestConvertMapToQueryString(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestConvertMapToQueryString")
|
||||
|
||||
var m = map[string]interface{}{
|
||||
var m = map[string]any{
|
||||
"c": 3,
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
@@ -47,6 +47,46 @@ func GetPublicIpInfo() (*PublicIpInfo, error) {
|
||||
return &ip, nil
|
||||
}
|
||||
|
||||
// GetIps return all ipv4 of system
|
||||
func GetIps() []string {
|
||||
var ips []string
|
||||
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
if err != nil {
|
||||
return ips
|
||||
}
|
||||
|
||||
for _, addr := range addrs {
|
||||
ipNet, isValid := addr.(*net.IPNet)
|
||||
if isValid && !ipNet.IP.IsLoopback() {
|
||||
if ipNet.IP.To4() != nil {
|
||||
ips = append(ips, ipNet.IP.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
return ips
|
||||
}
|
||||
|
||||
// GetMacAddrs get mac address
|
||||
func GetMacAddrs() []string {
|
||||
var macAddrs []string
|
||||
|
||||
nets, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return macAddrs
|
||||
}
|
||||
|
||||
for _, net := range nets {
|
||||
macAddr := net.HardwareAddr.String()
|
||||
if len(macAddr) == 0 {
|
||||
continue
|
||||
}
|
||||
macAddrs = append(macAddrs, macAddr)
|
||||
}
|
||||
|
||||
return macAddrs
|
||||
}
|
||||
|
||||
// PublicIpInfo public ip info: country, region, isp, city, lat, lon, ip
|
||||
type PublicIpInfo struct {
|
||||
Status string `json:"status"`
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func doHttpRequest(method, reqUrl string, params ...interface{}) (*http.Response, error) {
|
||||
func doHttpRequest(method, reqUrl string, params ...any) (*http.Response, error) {
|
||||
if len(reqUrl) == 0 {
|
||||
return nil, errors.New("url should be specified")
|
||||
}
|
||||
@@ -60,7 +60,7 @@ func doHttpRequest(method, reqUrl string, params ...interface{}) (*http.Response
|
||||
return resp, e
|
||||
}
|
||||
|
||||
func setHeaderAndQueryParam(req *http.Request, reqUrl string, header, queryParam interface{}) error {
|
||||
func setHeaderAndQueryParam(req *http.Request, reqUrl string, header, queryParam any) error {
|
||||
err := setHeader(req, header)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -72,7 +72,7 @@ func setHeaderAndQueryParam(req *http.Request, reqUrl string, header, queryParam
|
||||
return nil
|
||||
}
|
||||
|
||||
func setHeaderAndQueryAndBody(req *http.Request, reqUrl string, header, queryParam, body interface{}) error {
|
||||
func setHeaderAndQueryAndBody(req *http.Request, reqUrl string, header, queryParam, body any) error {
|
||||
err := setHeader(req, header)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -88,7 +88,7 @@ func setHeaderAndQueryAndBody(req *http.Request, reqUrl string, header, queryPar
|
||||
return nil
|
||||
}
|
||||
|
||||
func setHeader(req *http.Request, header interface{}) error {
|
||||
func setHeader(req *http.Request, header any) error {
|
||||
if header != nil {
|
||||
switch v := header.(type) {
|
||||
case map[string]string:
|
||||
@@ -122,11 +122,11 @@ func setUrl(req *http.Request, reqUrl string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func setQueryParam(req *http.Request, reqUrl string, queryParam interface{}) error {
|
||||
func setQueryParam(req *http.Request, reqUrl string, queryParam any) error {
|
||||
var values url.Values
|
||||
if queryParam != nil {
|
||||
switch v := queryParam.(type) {
|
||||
case map[string]interface{}:
|
||||
case map[string]any:
|
||||
values = url.Values{}
|
||||
for k := range v {
|
||||
values.Set(k, fmt.Sprintf("%v", v[k]))
|
||||
@@ -134,7 +134,7 @@ func setQueryParam(req *http.Request, reqUrl string, queryParam interface{}) err
|
||||
case url.Values:
|
||||
values = v
|
||||
default:
|
||||
return errors.New("query params type should be url.Values or map[string]interface{}")
|
||||
return errors.New("query params type should be url.Values or map[string]any")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,23 +155,20 @@ func setQueryParam(req *http.Request, reqUrl string, queryParam interface{}) err
|
||||
return nil
|
||||
}
|
||||
|
||||
func setBodyByte(req *http.Request, body interface{}) error {
|
||||
func setBodyByte(req *http.Request, body any) error {
|
||||
if body != nil {
|
||||
var bodyByte []byte
|
||||
if body != nil {
|
||||
switch v := body.(type) {
|
||||
case []byte:
|
||||
bodyByte = v
|
||||
default:
|
||||
return errors.New("body type should be []byte")
|
||||
}
|
||||
switch b := body.(type) {
|
||||
case []byte:
|
||||
req.Body = ioutil.NopCloser(bytes.NewReader(b))
|
||||
req.ContentLength = int64(len(b))
|
||||
default:
|
||||
return errors.New("body type should be []byte")
|
||||
}
|
||||
req.Body = ioutil.NopCloser(bytes.NewReader(bodyByte))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getClient(client interface{}) (*http.Client, error) {
|
||||
func getClient(client any) (*http.Client, error) {
|
||||
c := http.Client{}
|
||||
if client != nil {
|
||||
switch v := client.(type) {
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/internal"
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestGetInternalIp(t *testing.T) {
|
||||
@@ -42,3 +42,13 @@ func TestIsPublicIP(t *testing.T) {
|
||||
assert.Equal(expected[i], actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetIps(t *testing.T) {
|
||||
ips := GetIps()
|
||||
t.Log(ips)
|
||||
}
|
||||
|
||||
func TestGetMacAddrs(t *testing.T) {
|
||||
macAddrs := GetMacAddrs()
|
||||
t.Log(macAddrs)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ package random
|
||||
|
||||
import (
|
||||
crand "crypto/rand"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"time"
|
||||
@@ -48,3 +49,18 @@ func RandBytes(length int) []byte {
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// UUIdV4 generate a random UUID of version 4 according to RFC 4122
|
||||
func UUIdV4() (string, error) {
|
||||
uuid := make([]byte, 16)
|
||||
|
||||
n, err := io.ReadFull(crand.Reader, uuid)
|
||||
if n != len(uuid) || err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
uuid[8] = uuid[8]&^0xc0 | 0x80
|
||||
uuid[6] = uuid[6]&^0xf0 | 0x40
|
||||
|
||||
return fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:]), nil
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/internal"
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestRandString(t *testing.T) {
|
||||
@@ -47,3 +47,16 @@ func TestRandBytes(t *testing.T) {
|
||||
|
||||
assert.Equal([]byte{}, RandBytes(0))
|
||||
}
|
||||
|
||||
func TestUUIdV4(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestUUIdV4")
|
||||
|
||||
uuid, err := UUIdV4()
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
isUUiDV4 := regexp.MustCompile(`^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$`)
|
||||
assert.Equal(true, isUUiDV4.MatchString(uuid))
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/duke-git/lancet/internal"
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestRetryFailed(t *testing.T) {
|
||||
|
||||
771
slice/slice.go
771
slice/slice.go
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user