mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-08 06:32:28 +08:00
Compare commits
113 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c01b7e675 | ||
|
|
0247ac232a | ||
|
|
e77354d7ff | ||
|
|
8998dc35bb | ||
|
|
ad9fd196ce | ||
|
|
c8a65c33a4 | ||
|
|
69a797f8ed | ||
|
|
1e5b69e9bf | ||
|
|
275abcc8c2 | ||
|
|
065b3b84fe | ||
|
|
4bc43f3278 | ||
|
|
f3382ceac9 | ||
|
|
d20f8783b2 | ||
|
|
8432a4e1ee | ||
|
|
5a8ff17b52 | ||
|
|
6b46a0c05c | ||
|
|
4b8b624b4c | ||
|
|
f274375e62 | ||
|
|
6dc017a5fa | ||
|
|
e1fb97095d | ||
|
|
d8f5a15590 | ||
|
|
1202ac955d | ||
|
|
84b2cec9b5 | ||
|
|
2d01a13787 | ||
|
|
db9b045500 | ||
|
|
2701bcc4d2 | ||
|
|
b9745fd08b | ||
|
|
3b1597d6f7 | ||
|
|
40ab5e8f7b | ||
|
|
cacedf2a05 | ||
|
|
4fc391895b | ||
|
|
b419319e66 | ||
|
|
db34b5f69c | ||
|
|
ee44526d9e | ||
|
|
6576b1f0cb | ||
|
|
93108bafb9 | ||
|
|
07f5e0697f | ||
|
|
4ba91d7e4c | ||
|
|
ab81d9c283 | ||
|
|
a74038466f | ||
|
|
02daa7f6cb | ||
|
|
fef6fd7b9d | ||
|
|
f6cd98086f | ||
|
|
24eb2bbacd | ||
|
|
15c1537bf0 | ||
|
|
c02654559a | ||
|
|
634ca09e8c | ||
|
|
f2e743dcf4 | ||
|
|
f8f58cae10 | ||
|
|
215b79140d | ||
|
|
0bd675340f | ||
|
|
f3d73899b1 | ||
|
|
d4a20b239a | ||
|
|
4c28431451 | ||
|
|
168ed096c7 | ||
|
|
a060769635 | ||
|
|
0a99492cf6 | ||
|
|
fb3de03f37 | ||
|
|
43c2fd2a22 | ||
|
|
279d0754ba | ||
|
|
f133b32faa | ||
|
|
b98d5edbb5 | ||
|
|
9e39c31087 | ||
|
|
26bc40c614 | ||
|
|
76d68e326b | ||
|
|
67b4782ac2 | ||
|
|
1d8b9a2625 | ||
|
|
94ae1acc78 | ||
|
|
aece2995d6 | ||
|
|
f5ec5eb58d | ||
|
|
d62284e9a6 | ||
|
|
b6815224fd | ||
|
|
5931b882ee | ||
|
|
f8096e3585 | ||
|
|
979381bfb7 | ||
|
|
3e2c25f827 | ||
|
|
2c7bcc9fbb | ||
|
|
3a944ab12f | ||
|
|
387079d034 | ||
|
|
33e3631b72 | ||
|
|
b3149ea619 | ||
|
|
116ff284c3 | ||
|
|
0cb251f7b8 | ||
|
|
683def2242 | ||
|
|
d4a90f2869 | ||
|
|
be67de3b40 | ||
|
|
6898ed413e | ||
|
|
5dbdbcd651 | ||
|
|
ae0facd32d | ||
|
|
2d7e19fb87 | ||
|
|
24d4a03227 | ||
|
|
93fb089f6e | ||
|
|
2fe272f2ef | ||
|
|
77859ffa15 | ||
|
|
f83f47df3a | ||
|
|
885c08847d | ||
|
|
cc4a20751f | ||
|
|
b0d1d39452 | ||
|
|
02fa7bc8be | ||
|
|
433eb63b86 | ||
|
|
a2541dac03 | ||
|
|
690e746811 | ||
|
|
7cb97a26c5 | ||
|
|
39d373d37b | ||
|
|
1aefd6aa12 | ||
|
|
c7aa44b8a4 | ||
|
|
0e3dc68de5 | ||
|
|
4083e75ed4 | ||
|
|
1327eff62f | ||
|
|
eb24c37143 | ||
|
|
b7a6c91064 | ||
|
|
555e185871 | ||
|
|
cb0efc5cc7 |
2
.github/workflows/codecov.yml
vendored
2
.github/workflows/codecov.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
|||||||
fetch-depth: 2
|
fetch-depth: 2
|
||||||
- uses: actions/setup-go@v2
|
- uses: actions/setup-go@v2
|
||||||
with:
|
with:
|
||||||
go-version: "1.18"
|
go-version: "1.16"
|
||||||
- name: Run coverage
|
- name: Run coverage
|
||||||
run: go test -v ./... -coverprofile=coverage.txt -covermode=atomic
|
run: go test -v ./... -coverprofile=coverage.txt -covermode=atomic
|
||||||
- name: Upload coverage to Codecov
|
- name: Upload coverage to Codecov
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -6,4 +6,5 @@ fileutil/*.txt
|
|||||||
fileutil/*.zip
|
fileutil/*.zip
|
||||||
fileutil/*.link
|
fileutil/*.link
|
||||||
fileutil/unzip/*
|
fileutil/unzip/*
|
||||||
|
slice/testdata/*
|
||||||
cryptor/*.pem
|
cryptor/*.pem
|
||||||
764
README.md
764
README.md
@@ -3,13 +3,14 @@
|
|||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||

|

|
||||||
[](https://github.com/duke-git/lancet/releases)
|
[](https://github.com/duke-git/lancet/releases)
|
||||||
[](https://pkg.go.dev/github.com/duke-git/lancet/v2)
|
[](https://pkg.go.dev/github.com/duke-git/lancet)
|
||||||
[](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
|
[](https://goreportcard.com/report/github.com/duke-git/lancet)
|
||||||
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
||||||
[](https://codecov.io/gh/duke-git/lancet)
|
[](https://codecov.io/gh/duke-git/lancet)
|
||||||
[](https://github.com/duke-git/lancet/blob/main/LICENSE)
|
[](https://github.com/duke-git/lancet/blob/v1/LICENSE)
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
@@ -22,22 +23,15 @@ English | [简体中文](./README_zh-CN.md)
|
|||||||
|
|
||||||
## Feature
|
## Feature
|
||||||
|
|
||||||
- 👏 Comprehensive, efficient and reusable.
|
- 👏 Comprehensive, efficient and reusable.
|
||||||
- 💪 250+ go util functions, support string, slice, datetime, net, crypt...
|
- 💪 400+ go util functions, support string, slice, datetime, net, crypt...
|
||||||
- 💅 Only depend on the go standard library.
|
- 💅 Only depend on the go standard library.
|
||||||
- 🌍 Unit test for every exported function.
|
- 🌍 Unit test for every exported function.
|
||||||
|
|
||||||
## Installation
|
## 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
|
||||||
go get github.com/duke-git/lancet/v2 // will install latest version of v2.x.x
|
go get github.com/duke-git/lancet
|
||||||
```
|
|
||||||
|
|
||||||
2. <b>For users who use version below go1.18, you should install v1.x.x. now latest v1 is v1.2.9. </b>
|
|
||||||
```go
|
|
||||||
go get github.com/duke-git/lancet@v1.2.9 // below go1.18, install latest version of v1.x.x
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@@ -45,395 +39,461 @@ go get github.com/duke-git/lancet@v1.2.9 // below go1.18, install latest version
|
|||||||
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:
|
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
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/strutil"
|
import "github.com/duke-git/lancet/strutil"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
Here takes the string function ReverseStr (reverse order string) as an example, and the strutil package needs to be imported.
|
Here takes the string function Reverse (reverse order string) as an example, and the strutil package needs to be imported.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/strutil"
|
"github.com/duke-git/lancet/strutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := "hello"
|
s := "hello"
|
||||||
rs := strutil.ReverseStr(s)
|
rs := strutil.Reverse(s)
|
||||||
fmt.Println(rs) //olleh
|
fmt.Println(rs) //olleh
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## API Documentation
|
## API Documentation
|
||||||
|
|
||||||
### Algorithm package implements some basic algorithm. eg. sort, search.
|
### 1. Compare package provides a lightweight comparison function on any type.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/algorithm"
|
import "github.com/duke-git/lancet/compare"
|
||||||
```
|
|
||||||
#### 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)
|
|
||||||
|
|
||||||
|
|
||||||
### Convertor package contains some functions for data convertion.
|
|
||||||
|
|
||||||
```go
|
|
||||||
import "github.com/duke-git/lancet/v2/convertor"
|
|
||||||
```
|
|
||||||
#### 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
|
|
||||||
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.
|
- [Equal](https://github.com/duke-git/lancet/blob/v1/docs/compare.md#Equal)
|
||||||
|
- [EqualValue](https://github.com/duke-git/lancet/blob/v1/docs/compare.md#EqualValue)
|
||||||
|
- [LessThan](https://github.com/duke-git/lancet/blob/v1/docs/compare.md#LessThan)
|
||||||
|
- [GreaterThan](https://github.com/duke-git/lancet/blob/v1/docs/compare.md#GreaterThan)
|
||||||
|
- [LessOrEqual](https://github.com/duke-git/lancet/blob/v1/docs/compare.md#LessOrEqual)
|
||||||
|
- [GreaterOrEqual](https://github.com/duke-git/lancet/blob/v1/docs/compare.md#GreaterOrEqual)
|
||||||
|
|
||||||
|
### 2. Convertor package contains some functions for data convertion.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/datetime"
|
import "github.com/duke-git/lancet/convertor"
|
||||||
```
|
```
|
||||||
#### 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)
|
|
||||||
|
|
||||||
### Fileutil package implements some basic functions for file operations.
|
#### Function list:
|
||||||
|
|
||||||
|
- [ColorHexToRGB](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#ColorHexToRGB)
|
||||||
|
- [ColorRGBToHex](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#ColorRGBToHex)
|
||||||
|
- [ToBool](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#ToBool)
|
||||||
|
- [ToBytes](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#ToBytes)
|
||||||
|
- [ToChar](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#ToChar)
|
||||||
|
- [ToChannel](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#ToChannel)
|
||||||
|
- [ToInt](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#ToInt)
|
||||||
|
- [ToJson](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#ToJson)
|
||||||
|
- [ToString](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#ToString)
|
||||||
|
- [StructToMap](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#StructToMap)
|
||||||
|
- [EncodeByte](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#EncodeByte)
|
||||||
|
- [DecodeByte](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#DecodeByte)
|
||||||
|
- [DeepClone](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#DeepClone)
|
||||||
|
- [CopyProperties](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#CopyProperties)
|
||||||
|
- [ToInterface](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#ToInterface)
|
||||||
|
- [Utf8ToGbk](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#Utf8ToGbk)
|
||||||
|
- [GbkToUtf8](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#GbkToUtf8)
|
||||||
|
|
||||||
|
### 3. Cryptor package is for data encryption and decryption.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/fileutil"
|
import "github.com/duke-git/lancet/cryptor"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Function list:
|
||||||
|
|
||||||
|
- [AesEcbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#AesEcbEncrypt)
|
||||||
|
- [AesEcbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#AesEcbDecrypt)
|
||||||
|
- [AesCbcEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#AesCbcEncrypt)
|
||||||
|
- [AesCbcDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#AesCbcDecrypt)
|
||||||
|
- [AesCtrCrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#AesCtrCrypt)
|
||||||
|
- [AesCfbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#AesCfbEncrypt)
|
||||||
|
- [AesCfbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#AesCfbDecrypt)
|
||||||
|
- [AesOfbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#AesOfbEncrypt)
|
||||||
|
- [AesOfbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#AesOfbDecrypt)
|
||||||
|
- [Base64StdEncode](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Base64StdEncode)
|
||||||
|
- [Base64StdDecode](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Base64StdDecode)
|
||||||
|
- [DesEcbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#DesEcbEncrypt)
|
||||||
|
- [DesEcbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#DesEcbDecrypt)
|
||||||
|
- [DesCbcEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#DesCbcEncrypt)
|
||||||
|
- [DesCbcDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#DesCbcDecrypt)
|
||||||
|
- [DesCtrCrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#DesCtrCrypt)
|
||||||
|
- [DesCfbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#DesCfbEncrypt)
|
||||||
|
- [DesCfbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#DesCfbDecrypt)
|
||||||
|
- [DesOfbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#DesOfbEncrypt)
|
||||||
|
- [DesOfbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#DesOfbDecrypt)
|
||||||
|
- [HmacMd5](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#HmacMd5)
|
||||||
|
- [HmacSha1](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#HmacSha1)
|
||||||
|
- [HmacSha256](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#HmacSha256)
|
||||||
|
- [HmacSha512](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#HmacSha512)
|
||||||
|
- [Md5String](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Md5String)
|
||||||
|
- [Md5File](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Md5File)
|
||||||
|
- [Sha1](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Sha1)
|
||||||
|
- [Sha256](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Sha256)
|
||||||
|
- [Sha512](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Sha512)
|
||||||
|
- [GenerateRsaKey](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#GenerateRsaKey)
|
||||||
|
- [RsaEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#RsaEncrypt)
|
||||||
|
- [RsaDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#RsaDecrypt)
|
||||||
|
|
||||||
|
### 4. Datetime package supports date and time format and compare.
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "github.com/duke-git/lancet/datetime"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Function list:
|
||||||
|
|
||||||
|
- [AddDay](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#AddDay)
|
||||||
|
- [AddHour](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#AddHour)
|
||||||
|
- [AddMinute](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#AddMinute)
|
||||||
|
- [AddYear](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#AddYear)
|
||||||
|
- [BeginOfMinute](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfMinute)
|
||||||
|
- [BeginOfHour](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfHour)
|
||||||
|
- [BeginOfDay](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfDay)
|
||||||
|
- [BeginOfWeek](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfWeek)
|
||||||
|
- [BeginOfMonth](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfMonth)
|
||||||
|
- [BeginOfYear](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfYear)
|
||||||
|
- [EndOfMinute](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfMinute)
|
||||||
|
- [EndOfHour](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfHour)
|
||||||
|
- [EndOfDay](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfDay)
|
||||||
|
- [EndOfWeek](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfWeek)
|
||||||
|
- [EndOfMonth](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfMonth)
|
||||||
|
- [EndOfYear](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfYear)
|
||||||
|
- [GetNowDate](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#GetNowDate)
|
||||||
|
- [GetNowTime](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#GetNowTime)
|
||||||
|
- [GetNowDateTime](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#GetNowDateTime)
|
||||||
|
- [GetZeroHourTimestamp](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#GetZeroHourTimestamp)
|
||||||
|
- [GetNightTimestamp](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#GetNightTimestamp)
|
||||||
|
- [FormatTimeToStr](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#FormatTimeToStr)
|
||||||
|
- [FormatStrToTime](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#FormatStrToTime)
|
||||||
|
- [NewUnix](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#NewUnix)
|
||||||
|
- [NewUnixNow](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#NewUnixNow)
|
||||||
|
- [NewFormat](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#NewFormat)
|
||||||
|
- [NewISO8601](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#NewISO8601)
|
||||||
|
- [ToUnix](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#ToUnix)
|
||||||
|
- [ToFormat](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#ToFormat)
|
||||||
|
- [ToFormatForTpl](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#ToFormatForTpl)
|
||||||
|
- [ToIso8601](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#ToIso8601)
|
||||||
|
- [IsLeapYear](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#IsLeapYear)
|
||||||
|
- [BetweenSeconds](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BetweenSeconds)
|
||||||
|
- [DayOfYear](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#DayOfYear)
|
||||||
|
- [IsWeekend](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#IsWeekend)
|
||||||
|
|
||||||
|
### 5. Fileutil package implements some basic functions for file operations.
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "github.com/duke-git/lancet/fileutil"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
|
||||||
- [ClearFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#ClearFile)
|
- [ClearFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#ClearFile)
|
||||||
- [CreateFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#CreateFile)
|
- [CreateFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#CreateFile)
|
||||||
- [CopyFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#CopyFile)
|
- [CreateDir](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#CreateDir)
|
||||||
- [FileMode](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#FileMode)
|
- [CopyFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#CopyFile)
|
||||||
- [MiMeType](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#MiMeType)
|
- [FileMode](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#FileMode)
|
||||||
- [IsExist](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#IsExist)
|
- [MiMeType](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#MiMeType)
|
||||||
- [IsLink](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#IsLink)
|
- [IsExist](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#IsExist)
|
||||||
- [IsDir](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#IsDir)
|
- [IsLink](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#IsLink)
|
||||||
- [ListFileNames](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#ListFileNames)
|
- [IsDir](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#IsDir)
|
||||||
- [RemoveFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#RemoveFile)
|
- [ListFileNames](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#ListFileNames)
|
||||||
- [ReadFileToString](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#ReadFileToString)
|
- [RemoveFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#RemoveFile)
|
||||||
- [ReadFileByLine](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#ReadFileByLine)
|
- [ReadFileToString](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#ReadFileToString)
|
||||||
- [Zip](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#Zip)
|
- [ReadFileByLine](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#ReadFileByLine)
|
||||||
- [UnZip](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#UnZip)
|
- [Zip](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#Zip)
|
||||||
|
- [ZipAppendEntry](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#ZipAppendEntry)
|
||||||
|
- [UnZip](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#UnZip)
|
||||||
|
- [CurrentPath](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#CurrentPath)
|
||||||
|
- [IsZipFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#IsZipFile)
|
||||||
|
- [FileSize](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#FileSize)
|
||||||
|
- [MTime](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#MTime)
|
||||||
|
- [Sha](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#Sha)
|
||||||
|
- [ReadCsvFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#ReadCsvFile)
|
||||||
|
- [WriteCsvFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#WriteCsvFile)
|
||||||
|
- [WriteStringToFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#WriteStringToFile)
|
||||||
|
- [WriteBytesToFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#WriteBytesToFile)
|
||||||
|
|
||||||
### Formatter contains some functions for data formatting.
|
### 6. Formatter contains some functions for data formatting.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/formatter"
|
import "github.com/duke-git/lancet/formatter"
|
||||||
```
|
|
||||||
#### Function list:
|
|
||||||
- [Comma](https://github.com/duke-git/lancet/blob/main/docs/formatter.md#Comma)
|
|
||||||
|
|
||||||
### Function package can control the flow of function execution and support part of functional programming
|
|
||||||
|
|
||||||
```go
|
|
||||||
import "github.com/duke-git/lancet/v2/function"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 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)
|
|
||||||
|
|
||||||
|
|
||||||
### Maputil package includes some functions to manipulate map.
|
|
||||||
|
|
||||||
```go
|
|
||||||
import "github.com/duke-git/lancet/v2/maputil"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Function list:
|
|
||||||
- [ForEach](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#ForEach)
|
|
||||||
- [Filter](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#Filter)
|
|
||||||
- [Intersect](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#Intersect)
|
|
||||||
- [Keys](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#Keys)
|
|
||||||
- [Merge](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#Merge)
|
|
||||||
- [Minus](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#Minus)
|
|
||||||
- [Values](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#Values)
|
|
||||||
|
|
||||||
|
|
||||||
### Mathutil package implements some functions for math calculation.
|
|
||||||
|
|
||||||
```go
|
|
||||||
import "github.com/duke-git/lancet/v2/mathutil"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 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)
|
|
||||||
|
|
||||||
|
|
||||||
### Netutil package contains functions to get net information and send http request.
|
|
||||||
|
|
||||||
```go
|
|
||||||
import "github.com/duke-git/lancet/v2/netutil"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 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
|
|
||||||
import "github.com/duke-git/lancet/v2/random"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 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)
|
|
||||||
|
|
||||||
### Retry package is for executing a function repeatedly until it was successful or canceled by the context.
|
|
||||||
|
|
||||||
```go
|
|
||||||
import "github.com/duke-git/lancet/v2/retry"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 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
|
|
||||||
import "github.com/duke-git/lancet/v2/slice"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 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)
|
|
||||||
- [SymmetricDifference](https://github.com/duke-git/lancet/blob/main/docs/slice.md#SymmetricDifference)
|
|
||||||
- [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)
|
|
||||||
|
|
||||||
### Strutil package contains some functions to manipulate string.
|
|
||||||
```go
|
|
||||||
import "github.com/duke-git/lancet/v2/strutil"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
|
||||||
- [After](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#After)
|
- [Comma](https://github.com/duke-git/lancet/blob/v1/docs/formatter.md#Comma)
|
||||||
- [AfterLast](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#AfterLast)
|
- [Pretty](https://github.com/duke-git/lancet/blob/v1/docs/formatter.md#Pretty)
|
||||||
- [Before](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Before)
|
- [PrettyToWriter](https://github.com/duke-git/lancet/blob/v1/docs/formatter.md#PrettyToWriter)
|
||||||
- [BeforeLast](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#BeforeLast)
|
- [DecimalBytes](https://github.com/duke-git/lancet/blob/v1/docs/formatter.md#DecimalBytes)
|
||||||
- [CamelCase](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#CamelCase)
|
- [BinaryBytes](https://github.com/duke-git/lancet/blob/v1/docs/formatter.md#BinaryBytes)
|
||||||
- [Capitalize](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Capitalize)
|
- [ParseDecimalBytes](https://github.com/duke-git/lancet/blob/v1/docs/formatter.md#ParseDecimalBytes)
|
||||||
- [IsString](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#IsString)
|
- [ParseBinaryBytes](https://github.com/duke-git/lancet/blob/v1/docs/formatter.md#ParseBinaryBytes)
|
||||||
- [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)
|
### 7. Function package can control the flow of function execution and support part of functional programming
|
||||||
- [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
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/system"
|
import "github.com/duke-git/lancet/function"
|
||||||
```
|
|
||||||
#### 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)
|
|
||||||
|
|
||||||
### Validator package contains some functions for data validation.
|
|
||||||
|
|
||||||
```go
|
|
||||||
import "github.com/duke-git/lancet/v2/validator"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
|
||||||
- [ContainChinese](https://github.com/duke-git/lancet/blob/main/docs/validator.md#ContainChinese)
|
- [After](https://github.com/duke-git/lancet/blob/v1/docs/function.md#After)
|
||||||
- [ContainLetter](https://github.com/duke-git/lancet/blob/main/docs/validator.md#ContainLetter)
|
- [Before](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Before)
|
||||||
- [ContainLower](https://github.com/duke-git/lancet/blob/main/docs/validator.md#ContainLower)
|
- [Curry](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Curry)
|
||||||
- [ContainUpper](https://github.com/duke-git/lancet/blob/main/docs/validator.md#ContainUpper)
|
- [Compose](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Compose)
|
||||||
- [IsAlpha](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsAlpha)
|
- [Debounced](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Debounced)
|
||||||
- [IsAllUpper](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsAllUpper)
|
- [Delay](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Delay)
|
||||||
- [IsAllLower](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsAllLower)
|
- [Pipeline](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Pipeline)
|
||||||
- [IsBase64](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsBase64)
|
- [Schedule](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Schedule)
|
||||||
- [IsChineseMobile](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsChineseMobile)
|
- [Watcher](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Watcher)
|
||||||
- [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)
|
### 8. Mathutil package implements some functions for math calculation.
|
||||||
- [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
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/xerror"
|
import "github.com/duke-git/lancet/mathutil"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/xerror.md#Unwrap)
|
|
||||||
|
- [Exponent](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#Exponent)
|
||||||
|
- [Fibonacci](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#Fibonacci)
|
||||||
|
- [Factorial](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#Factorial)
|
||||||
|
- [Percent](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#Percent)
|
||||||
|
- [RoundToFloat](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#RoundToFloat)
|
||||||
|
- [RoundToString](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#RoundToString)
|
||||||
|
- [TruncRound](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#TruncRound)
|
||||||
|
- [AngleToRadian](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#AngleToRadian)
|
||||||
|
- [RadianToAngle](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#RadianToAngle)
|
||||||
|
- [PointDistance](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#PointDistance)
|
||||||
|
- [IsPrime](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#IsPrime)
|
||||||
|
- [GCD](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#GCD)
|
||||||
|
- [LCM](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#LCM)
|
||||||
|
- [Cos](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#Cos)
|
||||||
|
- [Sin](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#Sin)
|
||||||
|
- [Log](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#Log)
|
||||||
|
|
||||||
|
### 9. Netutil package contains functions to get net information and send http request.
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "github.com/duke-git/lancet/netutil"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Function list:
|
||||||
|
|
||||||
|
- [ConvertMapToQueryString](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#ConvertMapToQueryString)
|
||||||
|
- [EncodeUrl](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#EncodeUrl)
|
||||||
|
- [GetInternalIp](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#GetInternalIp)
|
||||||
|
- [GetIps](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#GetIps)
|
||||||
|
- [GetMacAddrs](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#GetMacAddrs)
|
||||||
|
- [GetPublicIpInfo](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#GetPublicIpInfo)
|
||||||
|
- [GetRequestPublicIp](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#GetRequestPublicIp)
|
||||||
|
- [IsPublicIP](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#IsPublicIP)
|
||||||
|
- [IsInternalIP](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#IsInternalIP)
|
||||||
|
- [HttpGet](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#HttpGet)
|
||||||
|
- [HttpDelete](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#HttpDelete)
|
||||||
|
- [HttpPost](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#HttpPost)
|
||||||
|
- [HttpPut](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#HttpPut)
|
||||||
|
- [HttpPatch](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#HttpPatch)
|
||||||
|
- [ParseHttpResponse](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#ParseHttpResponse)
|
||||||
|
- [UploadFile](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#UploadFile)
|
||||||
|
- [DownloadFile](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#DownloadFile)
|
||||||
|
- [IsPingConnected](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#IsPingConnected)
|
||||||
|
- [IsTelnetConnected](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#IsTelnetConnected)
|
||||||
|
|
||||||
|
### 10. Random package implements some basic functions to generate random int and string.
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "github.com/duke-git/lancet/random"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Function list:
|
||||||
|
|
||||||
|
- [RandBytes](https://github.com/duke-git/lancet/blob/v1/docs/random.md#RandBytes)
|
||||||
|
- [RandInt](https://github.com/duke-git/lancet/blob/v1/docs/random.md#RandInt)
|
||||||
|
- [RandString](https://github.com/duke-git/lancet/blob/v1/docs/random.md#RandString)
|
||||||
|
- [RandUpper](https://github.com/duke-git/lancet/blob/v1/docs/random.md#RandUpper)
|
||||||
|
- [RandLower](https://github.com/duke-git/lancet/blob/v1/docs/random.md#RandLower)
|
||||||
|
- [RandNumeral](https://github.com/duke-git/lancet/blob/v1/docs/random.md#RandNumeral)
|
||||||
|
- [RandNumeralOrLetter](https://github.com/duke-git/lancet/blob/v1/docs/random.md#RandNumeralOrLetter)
|
||||||
|
- [UUIdV4](https://github.com/duke-git/lancet/blob/v1/docs/random.md#UUIdV4)
|
||||||
|
- [RandUniqueIntSlice](https://github.com/duke-git/lancet/blob/v1/docs/random.md#RandUniqueIntSlice)
|
||||||
|
|
||||||
|
### 11. Retry package is for executing a function repeatedly until it was successful or canceled by the context.
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "github.com/duke-git/lancet/retry"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Function list:
|
||||||
|
|
||||||
|
- [Context](https://github.com/duke-git/lancet/blob/v1/docs/retry.md#Context)
|
||||||
|
- [Retry](https://github.com/duke-git/lancet/blob/v1/docs/retry.md#Retry)
|
||||||
|
- [RetryFunc](https://github.com/duke-git/lancet/blob/v1/docs/retry.md#RetryFunc)
|
||||||
|
- [RetryDuration](https://github.com/duke-git/lancet/blob/v1/docs/retry.md#RetryDuration)
|
||||||
|
- [RetryTimes](https://github.com/duke-git/lancet/blob/v1/docs/retry.md#RetryTimes)
|
||||||
|
|
||||||
|
### 12. Slice contains some functions to manipulate slice.
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "github.com/duke-git/lancet/slice"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Function list:
|
||||||
|
|
||||||
|
- [AppendIfAbsent](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#AppendIfAbsent)
|
||||||
|
- [Contain](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Contain)
|
||||||
|
- [ContainSubSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#ContainSubSlice)
|
||||||
|
- [Chunk](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Chunk)
|
||||||
|
- [Compact](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Compact)
|
||||||
|
- [Concat](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Concat)
|
||||||
|
- [Count](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Count)
|
||||||
|
- [Difference](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Difference)
|
||||||
|
- [DifferenceBy](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#DifferenceBy)
|
||||||
|
- [DeleteByIndex](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#DeleteByIndex)
|
||||||
|
- [Drop](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Drop)
|
||||||
|
- [Every](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Every)
|
||||||
|
- [Equal](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Equal)
|
||||||
|
- [EqualWith](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#EqualWith)
|
||||||
|
- [Filter](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Filter)
|
||||||
|
- [Find](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Find)
|
||||||
|
- [FindLast](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#FindLast)
|
||||||
|
- [FlattenDeep](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#FlattenDeep)
|
||||||
|
- [ForEach](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#ForEach)
|
||||||
|
- [GroupBy](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#GroupBy)
|
||||||
|
- [IntSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#IntSlice)
|
||||||
|
- [IndexOf](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#IndexOf)
|
||||||
|
- [LastIndexOf](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#LastIndexOf)
|
||||||
|
- [InterfaceSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#InterfaceSlice)
|
||||||
|
- [Intersection](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Intersection)
|
||||||
|
- [InsertByIndex](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#InsertByIndex)
|
||||||
|
- [Map](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Map)
|
||||||
|
- [ReverseSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#ReverseSlice)
|
||||||
|
- [Reduce](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Reduce)
|
||||||
|
- [Shuffle](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Shuffle)
|
||||||
|
- [SortByField](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#SortByField)
|
||||||
|
- [Some](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Some)
|
||||||
|
- [StringSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#StringSlice)
|
||||||
|
- [ToSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#ToSlice)
|
||||||
|
- [ToSlicePointer](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#ToSlice)
|
||||||
|
- [Unique](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Unique)
|
||||||
|
- [UniqueBy](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#UniqueBy)
|
||||||
|
- [Union](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Union)
|
||||||
|
- [UpdateByIndex](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#UpdateByIndex)
|
||||||
|
- [Without](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Without)
|
||||||
|
|
||||||
|
### 13. Strutil package contains some functions to manipulate string.
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "github.com/duke-git/lancet/strutil"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Function list:
|
||||||
|
|
||||||
|
- [After](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#After)
|
||||||
|
- [AfterLast](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#AfterLast)
|
||||||
|
- [Before](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Before)
|
||||||
|
- [BeforeLast](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#BeforeLast)
|
||||||
|
- [CamelCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#CamelCase)
|
||||||
|
- [Capitalize](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Capitalize)
|
||||||
|
- [ContainsAll](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#ContainsAll)
|
||||||
|
- [ContainsAny](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#ContainsAny)
|
||||||
|
- [IsString](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#IsString)
|
||||||
|
- [KebabCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#KebabCase)
|
||||||
|
- [UpperKebabCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#UpperKebabCase)
|
||||||
|
- [LowerFirst](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#LowerFirst)
|
||||||
|
- [UpperFirst](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#UpperFirst)
|
||||||
|
- [Pad](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Pad)
|
||||||
|
- [PadEnd](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#PadEnd)
|
||||||
|
- [PadStart](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#PadStart)
|
||||||
|
- [Reverse](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Reverse)
|
||||||
|
- [SnakeCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#SnakeCase)
|
||||||
|
- [UpperSnakeCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#UpperSnakeCase)
|
||||||
|
- [SplitEx](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#SplitEx)
|
||||||
|
- [Wrap](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Wrap)
|
||||||
|
- [Unwrap](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Unwrap)
|
||||||
|
- [SplitWords](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#SplitWords)
|
||||||
|
- [WordCount](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#WordCount)
|
||||||
|
- [RemoveNonPrintable](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#RemoveNonPrintable)
|
||||||
|
- [StringToBytes](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#StringToBytes)
|
||||||
|
- [BytesToString](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#BytesToString)
|
||||||
|
- [IsBlank](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#IsBlank)
|
||||||
|
- [HasPrefixAny](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#HasPrefixAny)
|
||||||
|
- [HasSuffixAny](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#HasSuffixAny)
|
||||||
|
- [IndexOffset](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#IndexOffset)
|
||||||
|
- [ReplaceWithMap](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#ReplaceWithMap)
|
||||||
|
- [Trim](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Trim)
|
||||||
|
- [SplitAndTrim](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#SplitAndTrim)
|
||||||
|
- [HideString](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#HideString)
|
||||||
|
- [RemoveWhiteSpace](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#RemoveWhiteSpace)
|
||||||
|
### 14. System package contain some functions about os, runtime, shell command.
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "github.com/duke-git/lancet/system"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Function list:
|
||||||
|
|
||||||
|
- [IsWindows](https://github.com/duke-git/lancet/blob/v1/docs/system.md#IsWindows)
|
||||||
|
- [IsLinux](https://github.com/duke-git/lancet/blob/v1/docs/system.md#IsLinux)
|
||||||
|
- [IsMac](https://github.com/duke-git/lancet/blob/v1/docs/system.md#IsMac)
|
||||||
|
- [GetOsEnv](https://github.com/duke-git/lancet/blob/v1/docs/system.md#GetOsEnv)
|
||||||
|
- [SetOsEnv](https://github.com/duke-git/lancet/blob/v1/docs/system.md#SetOsEnv)
|
||||||
|
- [RemoveOsEnv](https://github.com/duke-git/lancet/blob/v1/docs/system.md#RemoveOsEnv)
|
||||||
|
- [CompareOsEnv](https://github.com/duke-git/lancet/blob/v1/docs/system.md#CompareOsEnv)
|
||||||
|
- [ExecCommand](https://github.com/duke-git/lancet/blob/v1/docs/system.md#ExecCommand)
|
||||||
|
- [GetOsBits](https://github.com/duke-git/lancet/blob/v1/docs/system.md#GetOsBits)
|
||||||
|
|
||||||
|
### 15. Validator package contains some functions for data validation.
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "github.com/duke-git/lancet/validator"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Function list:
|
||||||
|
|
||||||
|
- [ContainChinese](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#ContainChinese)
|
||||||
|
- [ContainLetter](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#ContainLetter)
|
||||||
|
- [ContainLower](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#ContainLower)
|
||||||
|
- [ContainUpper](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#ContainUpper)
|
||||||
|
- [IsAlpha](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsAlpha)
|
||||||
|
- [IsAllUpper](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsAllUpper)
|
||||||
|
- [IsAllLower](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsAllLower)
|
||||||
|
- [IsBase64](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsBase64)
|
||||||
|
- [IsChineseMobile](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsChineseMobile)
|
||||||
|
- [IsChineseIdNum](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsChineseIdNum)
|
||||||
|
- [IsChinesePhone](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsChinesePhone)
|
||||||
|
- [IsCreditCard](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsCreditCard)
|
||||||
|
- [IsDns](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsDns)
|
||||||
|
- [IsEmail](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsEmail)
|
||||||
|
- [IsEmptyString](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsEmptyString)
|
||||||
|
- [IsInt](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsInt)
|
||||||
|
- [IsFloat](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsFloat)
|
||||||
|
- [IsNumber](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsNumber)
|
||||||
|
- [IsIntStr](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsIntStr)
|
||||||
|
- [IsFloatStr](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsFloatStr)
|
||||||
|
- [IsNumberStr](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsNumberStr)
|
||||||
|
- [IsJSON](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsJSON)
|
||||||
|
- [IsRegexMatch](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsRegexMatch)
|
||||||
|
- [IsIp](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsIp)
|
||||||
|
- [IsIpV4](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsIpV4)
|
||||||
|
- [IsIpV6](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsIpV6)
|
||||||
|
- [IsStrongPassword](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsStrongPassword)
|
||||||
|
- [IsUrl](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsUrl)
|
||||||
|
- [IsWeakPassword](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsWeakPassword)
|
||||||
|
- [IsZeroValue](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsZeroValue)
|
||||||
|
- [IsGBK](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsGBK)
|
||||||
|
- [IsASCII](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsASCII)
|
||||||
|
- [IsPrintable](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsPrintable)
|
||||||
|
|
||||||
## How to Contribute
|
## How to Contribute
|
||||||
|
|
||||||
|
|||||||
718
README_zh-CN.md
718
README_zh-CN.md
@@ -3,13 +3,14 @@
|
|||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||

|

|
||||||
[](https://github.com/duke-git/lancet/releases)
|
[](https://github.com/duke-git/lancet/releases)
|
||||||
[](https://pkg.go.dev/github.com/duke-git/lancet/v2)
|
[](https://pkg.go.dev/github.com/duke-git/lancet)
|
||||||
[](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
|
[](https://goreportcard.com/report/github.com/duke-git/lancet)
|
||||||
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
||||||
[](https://codecov.io/gh/duke-git/lancet)
|
[](https://codecov.io/gh/duke-git/lancet)
|
||||||
[](https://github.com/duke-git/lancet/blob/main/LICENSE)
|
[](https://github.com/duke-git/lancet/blob/v1/LICENSE)
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
@@ -19,430 +20,485 @@
|
|||||||
|
|
||||||
简体中文 | [English](./README.md)
|
简体中文 | [English](./README.md)
|
||||||
|
|
||||||
|
|
||||||
## 特性
|
## 特性
|
||||||
|
|
||||||
- 👏 全面、高效、可复用
|
- 👏 全面、高效、可复用
|
||||||
- 💪 250+常用go工具函数,支持string、slice、datetime、net、crypt...
|
- 💪 400+常用 go 工具函数,支持 string、slice、datetime、net、crypt...
|
||||||
- 💅 只依赖go标准库
|
- 💅 只依赖 go 标准库
|
||||||
- 🌍 所有导出函数单元测试覆盖率100%
|
- 🌍 所有导出函数单元测试覆盖率 100%
|
||||||
|
|
||||||
## 安装
|
## 安装
|
||||||
### Note:
|
|
||||||
1. <b>对于使用go1.18及以上的用户,建议安装v2.x.x。 因为v2.x.x用go1.18的泛型重写了大部分函数。</b>
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
go get github.com/duke-git/lancet/v2 //安装v2最新版本v2.x.x
|
go get github.com/duke-git/lancet
|
||||||
```
|
|
||||||
|
|
||||||
2. <b>使用go1.18以下版本的用户,必须安装v1.x.x。目前最新的v1版本是v1.2.9。</b>
|
|
||||||
```go
|
|
||||||
go get github.com/duke-git/lancet@v1.2.9 // 使用go1.18以下版本, 必须安装v1.x.x版本
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 用法
|
## 用法
|
||||||
|
|
||||||
lancet是以包的结构组织代码的,使用时需要导入相应的包名。例如:如果使用字符串相关函数,需要导入strutil包:
|
lancet 是以包的结构组织代码的,使用时需要导入相应的包名。例如:如果使用字符串相关函数,需要导入 strutil 包:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/strutil"
|
import "github.com/duke-git/lancet/strutil"
|
||||||
```
|
```
|
||||||
|
|
||||||
## 例子
|
## 例子
|
||||||
|
|
||||||
此处以字符串工具函数ReverseStr(逆序字符串)为例,需要导入strutil包:
|
此处以字符串工具函数 Reverse(逆序字符串)为例,需要导入 strutil 包:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/strutil"
|
"github.com/duke-git/lancet/strutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := "hello"
|
s := "hello"
|
||||||
rs := strutil.ReverseStr(s)
|
rs := strutil.Reverse(s)
|
||||||
fmt.Println(rs) //olleh
|
fmt.Println(rs) //olleh
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## API文档
|
## API 文档
|
||||||
|
|
||||||
### algorithm算法包实现一些基本算法。eg. sort, search.
|
|
||||||
|
|
||||||
|
### 1. compare包提供几个轻量级的类型比较函数。
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/algorithm"
|
import "github.com/duke-git/lancet/compare"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### 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转换器包支持一些常见的数据类型转换。
|
- [Equal](https://github.com/duke-git/lancet/blob/v1/docs/compare_zh-CN.md#Equal)
|
||||||
|
- [EqualValue](https://github.com/duke-git/lancet/blob/v1/docs/compare_zh-CN.md#EqualValue)
|
||||||
|
- [LessThan](https://github.com/duke-git/lancet/blob/v1/docs/compare_zh-CN.md#LessThan)
|
||||||
|
- [GreaterThan](https://github.com/duke-git/lancet/blob/v1/docs/compare_zh-CN.md#GreaterThan)
|
||||||
|
- [LessOrEqual](https://github.com/duke-git/lancet/blob/v1/docs/compare_zh-CN.md#LessOrEqual)
|
||||||
|
- [GreaterOrEqual](https://github.com/duke-git/lancet/blob/v1/docs/compare_zh-CN.md#GreaterOrEqual)
|
||||||
|
|
||||||
|
### 2. convertor转换器包支持一些常见的数据类型转换。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/convertor"
|
import "github.com/duke-git/lancet/convertor"
|
||||||
```
|
|
||||||
#### 函数列表:
|
|
||||||
- [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
|
|
||||||
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日期时间处理包,格式化日期,比较日期。
|
|
||||||
|
|
||||||
|
- [ColorHexToRGB](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#ColorHexToRGB)
|
||||||
|
- [ColorRGBToHex](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#ColorRGBToHex)
|
||||||
|
- [ToBool](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#ToBool)
|
||||||
|
- [ToBytes](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#ToBytes)
|
||||||
|
- [ToChar](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#ToChar)
|
||||||
|
- [ToChannel](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#ToChannel)
|
||||||
|
- [ToInt](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#ToInt)
|
||||||
|
- [ToJson](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#ToJson)
|
||||||
|
- [ToString](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#ToString)
|
||||||
|
- [StructToMap](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#StructToMap)
|
||||||
|
- [EncodeByte](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#EncodeByte)
|
||||||
|
- [DecodeByte](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#DecodeByte)
|
||||||
|
- [DeepClone](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#DeepClone)
|
||||||
|
- [CopyProperties](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#CopyProperties)
|
||||||
|
- [ToInterface](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#ToInterface)
|
||||||
|
- [Utf8ToGbk](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#Utf8ToGbk)
|
||||||
|
- [GbkToUtf8](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#GbkToUtf8)
|
||||||
|
### 3. cryptor 加密包支持数据加密和解密,获取 md5,hash 值。支持 base64, md5, hmac, aes, des, rsa。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/datetime"
|
import "github.com/duke-git/lancet/cryptor"
|
||||||
```
|
```
|
||||||
#### 函数列表:
|
|
||||||
- [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)
|
|
||||||
|
|
||||||
### fileutil包支持文件基本操作。
|
#### 函数列表:
|
||||||
|
|
||||||
|
- [AesEcbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#AesEcbEncrypt)
|
||||||
|
- [AesEcbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#AesEcbDecrypt)
|
||||||
|
- [AesCbcEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#AesCbcEncrypt)
|
||||||
|
- [AesCbcDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#AesCbcDecrypt)
|
||||||
|
- [AesCtrCrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#AesCtrCrypt)
|
||||||
|
- [AesCfbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#AesCfbEncrypt)
|
||||||
|
- [AesCfbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#AesCfbDecrypt)
|
||||||
|
- [AesOfbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#AesOfbEncrypt)
|
||||||
|
- [AesOfbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#AesOfbDecrypt)
|
||||||
|
- [Base64StdEncode](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Base64StdEncode)
|
||||||
|
- [Base64StdDecode](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Base64StdDecode)
|
||||||
|
- [DesEcbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#DesEcbEncrypt)
|
||||||
|
- [DesEcbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#DesEcbDecrypt)
|
||||||
|
- [DesCbcEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#DesCbcEncrypt)
|
||||||
|
- [DesCbcDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#DesCbcDecrypt)
|
||||||
|
- [DesCtrCrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#DesCtrCrypt)
|
||||||
|
- [DesCfbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#DesCfbEncrypt)
|
||||||
|
- [DesCfbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#DesCfbDecrypt)
|
||||||
|
- [DesOfbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#DesOfbEncrypt)
|
||||||
|
- [DesOfbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#DesOfbDecrypt)
|
||||||
|
- [HmacMd5](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#HmacMd5)
|
||||||
|
- [HmacSha1](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#HmacSha1)
|
||||||
|
- [HmacSha256](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#HmacSha256)
|
||||||
|
- [HmacSha512](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#HmacSha512)
|
||||||
|
- [Md5String](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Md5String)
|
||||||
|
- [Md5File](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Md5File)
|
||||||
|
- [Sha1](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Sha1)
|
||||||
|
- [Sha256](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Sha256)
|
||||||
|
- [Sha512](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Sha512)
|
||||||
|
- [GenerateRsaKey](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#GenerateRsaKey)
|
||||||
|
- [RsaEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#RsaEncrypt)
|
||||||
|
- [RsaDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#RsaDecrypt)
|
||||||
|
|
||||||
|
### 4. datetime 日期时间处理包,格式化日期,比较日期。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/fileutil"
|
import "github.com/duke-git/lancet/datetime"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 函数列表:
|
||||||
|
|
||||||
|
- [AddDay](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#AddDay)
|
||||||
|
- [AddHour](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#AddHour)
|
||||||
|
- [AddMinute](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#AddMinute)
|
||||||
|
- [AddYear](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#AddYear)
|
||||||
|
- [BeginOfMinute](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfMinute)
|
||||||
|
- [BeginOfHour](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfHour)
|
||||||
|
- [BeginOfDay](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfDay)
|
||||||
|
- [BeginOfWeek](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfWeek)
|
||||||
|
- [BeginOfMonth](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfMonth)
|
||||||
|
- [BeginOfYear](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfYear)
|
||||||
|
- [EndOfMinute](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfMinute)
|
||||||
|
- [EndOfHour](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfHour)
|
||||||
|
- [EndOfDay](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfDay)
|
||||||
|
- [EndOfWeek](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfWeek)
|
||||||
|
- [EndOfMonth](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfMonth)
|
||||||
|
- [EndOfYear](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfYear)
|
||||||
|
- [GetNowDate](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#GetNowDate)
|
||||||
|
- [GetNowTime](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#GetNowTime)
|
||||||
|
- [GetNowDateTime](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#GetNowDateTime)
|
||||||
|
- [GetZeroHourTimestamp](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#GetZeroHourTimestamp)
|
||||||
|
- [GetNightTimestamp](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#GetNightTimestamp)
|
||||||
|
- [FormatTimeToStr](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#FormatTimeToStr)
|
||||||
|
- [FormatStrToTime](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#FormatStrToTime)
|
||||||
|
- [NewUnix](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#NewUnix)
|
||||||
|
- [NewUnixNow](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#NewUnixNow)
|
||||||
|
- [NewFormat](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#NewFormat)
|
||||||
|
- [NewISO8601](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#NewISO8601)
|
||||||
|
- [ToUnix](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#ToUnix)
|
||||||
|
- [ToFormat](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#ToFormat)
|
||||||
|
- [ToFormatForTpl](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#ToFormatForTpl)
|
||||||
|
- [ToIso8601](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#ToIso8601)
|
||||||
|
- [IsLeapYear](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#IsLeapYear)
|
||||||
|
- [BetweenSeconds](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#BetweenSeconds)
|
||||||
|
- [DayOfYear](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#DayOfYear)
|
||||||
|
- [IsWeekend](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#IsWeekend)
|
||||||
|
|
||||||
|
### 5. fileutil 包支持文件基本操作。
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "github.com/duke-git/lancet/fileutil"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 函数列表:
|
#### 函数列表:
|
||||||
|
|
||||||
- [ClearFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#ClearFile)
|
- [ClearFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#ClearFile)
|
||||||
- [CreateFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#CreateFile)
|
- [CreateFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#CreateFile)
|
||||||
- [CopyFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#CopyFile)
|
- [CreateDir](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#CreateDir)
|
||||||
- [FileMode](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#FileMode)
|
- [CopyFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#CopyFile)
|
||||||
- [MiMeType](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#MiMeType)
|
- [FileMode](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#FileMode)
|
||||||
- [IsExist](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#IsExist)
|
- [MiMeType](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#MiMeType)
|
||||||
- [IsLink](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#IsLink)
|
- [IsExist](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#IsExist)
|
||||||
- [IsDir](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#IsDir)
|
- [IsLink](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#IsLink)
|
||||||
- [ListFileNames](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#ListFileNames)
|
- [IsDir](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#IsDir)
|
||||||
- [RemoveFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#RemoveFile)
|
- [ListFileNames](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#ListFileNames)
|
||||||
- [ReadFileToString](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#ReadFileToString)
|
- [RemoveFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#RemoveFile)
|
||||||
- [ReadFileByLine](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#ReadFileByLine)
|
- [ReadFileToString](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#ReadFileToString)
|
||||||
- [Zip](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#Zip)
|
- [ReadFileByLine](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#ReadFileByLine)
|
||||||
- [UnZip](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#UnZip)
|
- [Zip](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#Zip)
|
||||||
|
- [ZipAppendEntry](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#ZipAppendEntry)
|
||||||
|
- [UnZip](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#UnZip)
|
||||||
|
- [CurrentPath](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#CurrentPath)
|
||||||
|
- [IsZipFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#IsZipFile)
|
||||||
|
- [FileSize](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#FileSize)
|
||||||
|
- [MTime](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#MTime)
|
||||||
|
- [Sha](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#Sha)
|
||||||
|
- [ReadCsvFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#ReadCsvFile)
|
||||||
|
- [WriteCsvFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#WriteCsvFile)
|
||||||
|
- [WriteStringToFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#WriteStringToFile)
|
||||||
|
- [WriteBytesToFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#WriteBytesToFile)
|
||||||
|
|
||||||
### formatter格式化器包含一些数据格式化处理方法。
|
### 6. formatter 格式化器包含一些数据格式化处理方法。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/formatter"
|
import "github.com/duke-git/lancet/formatter"
|
||||||
```
|
|
||||||
#### 函数列表:
|
|
||||||
- [Comma](https://github.com/duke-git/lancet/blob/main/docs/formatter_zh-CN.md#Comma)
|
|
||||||
|
|
||||||
|
|
||||||
### function函数包控制函数执行流程,包含部分函数式编程。
|
|
||||||
|
|
||||||
```go
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
- [Comma](https://github.com/duke-git/lancet/blob/v1/docs/formatter_zh-CN.md#Comma)
|
||||||
|
- [Pretty](https://github.com/duke-git/lancet/blob/v1/docs/formatter_zh-CN.md#Pretty)
|
||||||
|
- [PrettyToWriter](https://github.com/duke-git/lancet/blob/v1/docs/formatter_zh-CN.md#PrettyToWriter)
|
||||||
|
- [DecimalBytes](https://github.com/duke-git/lancet/blob/v1/docs/formatter_zh-CN.md#DecimalBytes)
|
||||||
|
- [BinaryBytes](https://github.com/duke-git/lancet/blob/v1/docs/formatter_zh-CN.md#BinaryBytes)
|
||||||
|
- [ParseDecimalBytes](https://github.com/duke-git/lancet/blob/v1/docs/formatter_zh-CN.md#ParseDecimalBytes)
|
||||||
|
- [ParseBinaryBytes](https://github.com/duke-git/lancet/blob/v1/docs/formatter_zh-CN.md#ParseBinaryBytes)
|
||||||
|
|
||||||
### maputil包包括一些操作map的函数.
|
### 7. function 函数包控制函数执行流程,包含部分函数式编程。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/maputil"
|
import "github.com/duke-git/lancet/function"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 函数列表:
|
#### 函数列表:
|
||||||
- [ForEach](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#ForEach)
|
|
||||||
- [Filter](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#Filter)
|
|
||||||
- [Intersect](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#Intersect)
|
|
||||||
- [Keys](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#Keys)
|
|
||||||
- [Merge](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#Merge)
|
|
||||||
- [Minus](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#Minus)
|
|
||||||
- [Values](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#Values)
|
|
||||||
|
|
||||||
### mathutil包实现了一些数学计算的函数。
|
- [After](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#After)
|
||||||
|
- [Before](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Before)
|
||||||
|
- [Curry](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Curry)
|
||||||
|
- [Compose](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Compose)
|
||||||
|
- [Debounced](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Debounced)
|
||||||
|
- [Delay](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Delay)
|
||||||
|
- [Pipeline](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Pipeline)
|
||||||
|
- [Schedule](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Schedule)
|
||||||
|
- [Watcher](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Watcher)
|
||||||
|
|
||||||
|
### 8. mathutil 包实现了一些数学计算的函数。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/mathutil"
|
import "github.com/duke-git/lancet/mathutil"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function list:
|
#### 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)
|
|
||||||
|
|
||||||
### netutil网络包支持获取ip地址,发送http请求。
|
- [Exponent](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#Exponent)
|
||||||
|
- [Fibonacci](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#Fibonacci)
|
||||||
|
- [Factorial](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#Factorial)
|
||||||
|
- [Percent](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#Percent)
|
||||||
|
- [RoundToFloat](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#RoundToFloat)
|
||||||
|
- [RoundToString](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#RoundToString)
|
||||||
|
- [TruncRound](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#TruncRound)
|
||||||
|
- [AngleToRadian](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#AngleToRadian)
|
||||||
|
- [RadianToAngle](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#RadianToAngle)
|
||||||
|
- [PointDistance](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#PointDistance)
|
||||||
|
- [IsPrime](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#IsPrime)
|
||||||
|
- [GCD](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#GCD)
|
||||||
|
- [LCM](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#LCM)
|
||||||
|
- [Cos](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#Cos)
|
||||||
|
- [Sin](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#Sin)
|
||||||
|
- [Log](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#Log)
|
||||||
|
### 9. netutil 网络包支持获取 ip 地址,发送 http 请求。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/netutil"
|
import "github.com/duke-git/lancet/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
|
|
||||||
import "github.com/duke-git/lancet/v2/random"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 函数列表:
|
|
||||||
- [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
|
|
||||||
import "github.com/duke-git/lancet/v2/retry"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 函数列表:
|
|
||||||
- [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
|
|
||||||
import "github.com/duke-git/lancet/v2/slice"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 函数列表:
|
|
||||||
- [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)
|
|
||||||
- [SymmetricDifference](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#SymmetricDifference)
|
|
||||||
- [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)
|
|
||||||
|
|
||||||
|
|
||||||
### strutil包含处理字符串的相关函数。
|
|
||||||
|
|
||||||
```go
|
|
||||||
import "github.com/duke-git/lancet/v2/strutil"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 函数列表:
|
#### 函数列表:
|
||||||
|
|
||||||
- [After](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#After)
|
- [ConvertMapToQueryString](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#ConvertMapToQueryString)
|
||||||
- [AfterLast](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#AfterLast)
|
- [EncodeUrl](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#EncodeUrl)
|
||||||
- [Before](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Before)
|
- [GetInternalIp](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#GetInternalIp)
|
||||||
- [BeforeLast](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#BeforeLast)
|
- [GetIps](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#GetIps)
|
||||||
- [CamelCase](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#CamelCase)
|
- [GetMacAddrs](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#GetMacAddrs)
|
||||||
- [Capitalize](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Capitalize)
|
- [GetPublicIpInfo](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#GetPublicIpInfo)
|
||||||
- [IsString](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#IsString)
|
- [GetRequestPublicIp](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#GetRequestPublicIp)
|
||||||
- [KebabCase](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#KebabCase)
|
- [IsPublicIP](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#IsPublicIP)
|
||||||
- [LowerFirst](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#LowerFirst)
|
- [IsInternalIP](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#IsInternalIP)
|
||||||
- [UpperFirst](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#UpperFirst)
|
- [HttpGet](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#HttpGet)
|
||||||
- [PadEnd](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#PadEnd)
|
- [HttpDelete](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#HttpDelete)
|
||||||
- [PadStart](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#PadStart)
|
- [HttpPost](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#HttpPost)
|
||||||
- [ReverseStr](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#ReverseStr)
|
- [HttpPut](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#HttpPut)
|
||||||
- [SnakeCase](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#SnakeCase)
|
- [HttpPatch](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#HttpPatch)
|
||||||
- [Wrap](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Wrap)
|
- [ParseHttpResponse](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#ParseHttpResponse)
|
||||||
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Unwrap)
|
- [UploadFile](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#UploadFile)
|
||||||
|
- [DownloadFile](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#DownloadFile)
|
||||||
|
- [IsPingConnected](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#IsPingConnected)
|
||||||
|
- [IsTelnetConnected](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#IsTelnetConnected)
|
||||||
|
|
||||||
### system包含os, runtime, shell command相关函数。
|
### 10. random 随机数生成器包,可以生成随机[]bytes, int, string。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/system"
|
import "github.com/duke-git/lancet/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)
|
|
||||||
|
|
||||||
### validator验证器包,包含常用字符串格式验证函数。
|
- [RandBytes](https://github.com/duke-git/lancet/blob/v1/docs/random_zh-CN.md#RandBytes)
|
||||||
|
- [RandInt](https://github.com/duke-git/lancet/blob/v1/docs/random_zh-CN.md#RandInt)
|
||||||
|
- [RandString](https://github.com/duke-git/lancet/blob/v1/docs/random_zh-CN.md#RandString)
|
||||||
|
- [RandUpper](https://github.com/duke-git/lancet/blob/v1/docs/random_zh-CN.md#RandUpper)
|
||||||
|
- [RandLower](https://github.com/duke-git/lancet/blob/v1/docs/random_zh-CN.md#RandLower)
|
||||||
|
- [RandNumeral](https://github.com/duke-git/lancet/blob/v1/docs/random_zh-CN.md#RandNumeral)
|
||||||
|
- [RandNumeralOrLetter](https://github.com/duke-git/lancet/blob/v1/docs/random_zh-CN.md#RandNumeralOrLetter)
|
||||||
|
- [UUIdV4](https://github.com/duke-git/lancet/blob/v1/docs/random.md#UUIdV4)
|
||||||
|
- [RandUniqueIntSlice](https://github.com/duke-git/lancet/blob/v1/docs/random.md#RandUniqueIntSlice)
|
||||||
|
|
||||||
|
### 11. retry 重试执行函数直到函数运行成功或被 context cancel。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/validator"
|
import "github.com/duke-git/lancet/retry"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 函数列表:
|
#### 函数列表:
|
||||||
|
|
||||||
- [ContainChinese](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#ContainChinese)
|
- [Context](https://github.com/duke-git/lancet/blob/v1/docs/retry_zh-CN.md#Context)
|
||||||
- [ContainLetter](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#ContainLetter)
|
- [Retry](https://github.com/duke-git/lancet/blob/v1/docs/retry_zh-CN.md#Retry)
|
||||||
- [ContainLower](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#ContainLower)
|
- [RetryFunc](https://github.com/duke-git/lancet/blob/v1/docs/retry_zh-CN.md#RetryFunc)
|
||||||
- [ContainUpper](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#ContainUpper)
|
- [RetryDuration](https://github.com/duke-git/lancet/blob/v1/docs/retry_zh-CN.md#RetryDuration)
|
||||||
- [IsAlpha](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsAlpha)
|
- [RetryTimes](https://github.com/duke-git/lancet/blob/v1/docs/retry_zh-CN.md#RetryTimes)
|
||||||
- [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)
|
### 12. slice 包包含操作切片的方法集合。
|
||||||
### xerror包实现一些错误处理函数
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/duke-git/lancet/v2/xerror"
|
import "github.com/duke-git/lancet/slice"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 函数列表:
|
#### 函数列表:
|
||||||
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#Unwrap)
|
|
||||||
|
- [AppendIfAbsent](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#AppendIfAbsent)
|
||||||
|
- [Contain](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Contain)
|
||||||
|
- [ContainSubSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#ContainSubSlice)
|
||||||
|
- [Chunk](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Chunk)
|
||||||
|
- [Compact](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Compact)
|
||||||
|
- [Concat](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Concat)
|
||||||
|
- [Count](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Count)
|
||||||
|
- [Difference](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Difference)
|
||||||
|
- [DifferenceBy](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#DifferenceBy)
|
||||||
|
- [DeleteByIndex](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#DeleteByIndex)
|
||||||
|
- [Drop](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Drop)
|
||||||
|
- [Every](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Every)
|
||||||
|
- [Equal](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Equal)
|
||||||
|
- [EqualWith](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#EqualWith)
|
||||||
|
- [Filter](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Filter)
|
||||||
|
- [Find](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Find)
|
||||||
|
- [FindLast](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#FindLast)
|
||||||
|
- [FlattenDeep](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#FlattenDeep)
|
||||||
|
- [ForEach](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#ForEach)
|
||||||
|
- [GroupBy](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#GroupBy)
|
||||||
|
- [IntSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#IntSlice)
|
||||||
|
- [IndexOf](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#IndexOf)
|
||||||
|
- [LastIndexOf](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#LastIndexOf)
|
||||||
|
- [InterfaceSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#InterfaceSlice)
|
||||||
|
- [Intersection](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Intersection)
|
||||||
|
- [InsertByIndex](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#InsertByIndex)
|
||||||
|
- [Map](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Map)
|
||||||
|
- [ReverseSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#ReverseSlice)
|
||||||
|
- [Reduce](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Reduce)
|
||||||
|
- [Shuffle](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Shuffle)
|
||||||
|
- [SortByField](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#SortByField)
|
||||||
|
- [Some](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Some)
|
||||||
|
- [StringSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#StringSlice)
|
||||||
|
- [ToSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#ToSlice)
|
||||||
|
- [ToSlicePointer](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#ToSlice)
|
||||||
|
- [Unique](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Unique)
|
||||||
|
- [UniqueBy](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#UniqueBy)
|
||||||
|
- [Union](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Union)
|
||||||
|
- [UpdateByIndex](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#UpdateByIndex)
|
||||||
|
- [Without](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Without)
|
||||||
|
|
||||||
|
### 13. strutil 包含处理字符串的相关函数。
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "github.com/duke-git/lancet/strutil"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 函数列表:
|
||||||
|
|
||||||
|
- [After](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#After)
|
||||||
|
- [AfterLast](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#AfterLast)
|
||||||
|
- [Before](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Before)
|
||||||
|
- [BeforeLast](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#BeforeLast)
|
||||||
|
- [CamelCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#CamelCase)
|
||||||
|
- [Capitalize](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Capitalize)
|
||||||
|
- [ContainsAll](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#ContainsAll)
|
||||||
|
- [ContainsAny](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#ContainsAny)
|
||||||
|
- [IsString](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#IsString)
|
||||||
|
- [KebabCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#KebabCase)
|
||||||
|
- [UpperKebabCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#UpperKebabCase)
|
||||||
|
- [LowerFirst](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#LowerFirst)
|
||||||
|
- [UpperFirst](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#UpperFirst)
|
||||||
|
- [Pad](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Pad)
|
||||||
|
- [PadEnd](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#PadEnd)
|
||||||
|
- [PadStart](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#PadStart)
|
||||||
|
- [Reverse](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Reverse)
|
||||||
|
- [SnakeCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#SnakeCase)
|
||||||
|
- [UpperSnakeCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#UpperSnakeCase)
|
||||||
|
- [SplitEx](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#SplitEx)
|
||||||
|
- [Wrap](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Wrap)
|
||||||
|
- [Unwrap](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Unwrap)
|
||||||
|
- [SplitWords](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#SplitWords)
|
||||||
|
- [WordCount](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#WordCount)
|
||||||
|
- [RemoveNonPrintable](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#RemoveNonPrintable)
|
||||||
|
- [StringToBytes](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#StringToBytes)
|
||||||
|
- [BytesToString](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#BytesToString)
|
||||||
|
- [IsBlank](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#IsBlank)
|
||||||
|
- [HasPrefixAny](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#HasPrefixAny)
|
||||||
|
- [HasSuffixAny](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#HasSuffixAny)
|
||||||
|
- [IndexOffset](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#IndexOffset)
|
||||||
|
- [ReplaceWithMap](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#ReplaceWithMap)
|
||||||
|
- [Trim](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Trim)
|
||||||
|
- [SplitAndTrim](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#SplitAndTrim)
|
||||||
|
- [HideString](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#HideString)
|
||||||
|
- [RemoveWhiteSpace](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#RemoveWhiteSpace)
|
||||||
|
|
||||||
|
### 14. system 包含 os, runtime, shell command 相关函数。
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "github.com/duke-git/lancet/system"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 函数列表:
|
||||||
|
|
||||||
|
- [IsWindows](https://github.com/duke-git/lancet/blob/v1/docs/system_zh-CN.md#IsWindows)
|
||||||
|
- [IsLinux](https://github.com/duke-git/lancet/blob/v1/docs/system_zh-CN.md#IsLinux)
|
||||||
|
- [IsMac](https://github.com/duke-git/lancet/blob/v1/docs/system_zh-CN.md#IsMac)
|
||||||
|
- [GetOsEnv](https://github.com/duke-git/lancet/blob/v1/docs/system_zh-CN.md#GetOsEnv)
|
||||||
|
- [SetOsEnv](https://github.com/duke-git/lancet/blob/v1/docs/system_zh-CN.md#SetOsEnv)
|
||||||
|
- [RemoveOsEnv](https://github.com/duke-git/lancet/blob/v1/docs/system_zh-CN.md#RemoveOsEnv)
|
||||||
|
- [CompareOsEnv](https://github.com/duke-git/lancet/blob/v1/docs/system_zh-CN.md#CompareOsEnv)
|
||||||
|
- [ExecCommand](https://github.com/duke-git/lancet/blob/v1/docs/system_zh-CN.md#ExecCommand)
|
||||||
|
- [GetOsBits](https://github.com/duke-git/lancet/blob/v1/docs/system_zh-CN.md#GetOsBits)
|
||||||
|
|
||||||
|
### 15. validator 验证器包,包含常用字符串格式验证函数。
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "github.com/duke-git/lancet/validator"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 函数列表:
|
||||||
|
|
||||||
|
- [ContainChinese](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#ContainChinese)
|
||||||
|
- [ContainLetter](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#ContainLetter)
|
||||||
|
- [ContainLower](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#ContainLower)
|
||||||
|
- [ContainUpper](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#ContainUpper)
|
||||||
|
- [IsAlpha](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsAlpha)
|
||||||
|
- [IsAllUpper](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsAllUpper)
|
||||||
|
- [IsAllLower](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsAllLower)
|
||||||
|
- [IsBase64](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsBase64)
|
||||||
|
- [IsChineseMobile](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsChineseMobile)
|
||||||
|
- [IsChineseIdNum](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsChineseIdNum)
|
||||||
|
- [IsChinesePhone](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsChinesePhone)
|
||||||
|
- [IsCreditCard](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsCreditCard)
|
||||||
|
- [IsDns](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsDns)
|
||||||
|
- [IsEmail](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsEmail)
|
||||||
|
- [IsEmptyString](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsEmptyString)
|
||||||
|
- [IsInt](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsInt)
|
||||||
|
- [IsFloat](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsFloat)
|
||||||
|
- [IsNumber](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsNumber)
|
||||||
|
- [IsIntStr](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsIntStr)
|
||||||
|
- [IsFloatStr](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsFloatStr)
|
||||||
|
- [IsNumberStr](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsNumberStr)
|
||||||
|
- [IsJSON](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsJSON)
|
||||||
|
- [IsRegexMatch](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsRegexMatch)
|
||||||
|
- [IsIp](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsIp)
|
||||||
|
- [IsIpV4](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsIpV4)
|
||||||
|
- [IsIpV6](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsIpV6)
|
||||||
|
- [IsStrongPassword](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsStrongPassword)
|
||||||
|
- [IsUrl](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsUrl)
|
||||||
|
- [IsWeakPassword](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsWeakPassword)
|
||||||
|
- [IsZeroValue](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsZeroValue)
|
||||||
|
- [IsGBK](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsGBK)
|
||||||
|
- [IsASCII](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsASCII)
|
||||||
|
- [IsPrintable](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsPrintable)
|
||||||
|
|
||||||
## 如何贡献代码
|
## 如何贡献代码
|
||||||
|
|
||||||
非常感激任何的代码提交以使lancet的功能越来越强大。创建pull request时请遵守以下规则。
|
非常感激任何的代码提交以使 lancet 的功能越来越强大。创建 pull request 时请遵守以下规则。
|
||||||
|
|
||||||
1. Fork lancet仓库。
|
1. Fork lancet 仓库。
|
||||||
2. 创建自己的特性分支。
|
2. 创建自己的特性分支。
|
||||||
3. 提交变更。
|
3. 提交变更。
|
||||||
4. Push分支。
|
4. Push 分支。
|
||||||
5. 创建新的pull request。
|
5. 创建新的 pull request。
|
||||||
|
|||||||
@@ -1,102 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
// 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
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
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))
|
|
||||||
}
|
|
||||||
@@ -1,188 +0,0 @@
|
|||||||
// 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) {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// InsertionSort use insertion to sort slice.
|
|
||||||
func InsertionSort[T any](slice []T, comparator lancetconstraints.Comparator) {
|
|
||||||
for i := 0; i < len(slice); i++ {
|
|
||||||
for j := i; j > 0; j-- {
|
|
||||||
isPreLessThanCurrent := comparator.Compare(slice[j], slice[j-1]) == -1
|
|
||||||
if isPreLessThanCurrent {
|
|
||||||
swap(slice, j, j-1)
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SelectionSort use selection to sort slice.
|
|
||||||
func SelectionSort[T any](slice []T, comparator lancetconstraints.Comparator) {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShellSort shell sort slice.
|
|
||||||
func ShellSort[T any](slice []T, comparator lancetconstraints.Comparator) {
|
|
||||||
size := len(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 = gap / 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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) {
|
|
||||||
if lowIndex < highIndex {
|
|
||||||
p := partition(slice, lowIndex, highIndex, comparator)
|
|
||||||
QuickSort(slice, lowIndex, p-1, comparator)
|
|
||||||
QuickSort(slice, p+1, highIndex, comparator)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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) {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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, comparator lancetconstraints.Comparator) {
|
|
||||||
mergeSort(slice, 0, len(slice)-1, comparator)
|
|
||||||
}
|
|
||||||
|
|
||||||
func mergeSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) {
|
|
||||||
if lowIndex < highIndex {
|
|
||||||
mid := (lowIndex + highIndex) / 2
|
|
||||||
mergeSort(slice, lowIndex, mid, comparator)
|
|
||||||
mergeSort(slice, mid+1, highIndex, comparator)
|
|
||||||
merge(slice, lowIndex, mid, highIndex, comparator)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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]
|
|
||||||
}
|
|
||||||
@@ -1,218 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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")
|
|
||||||
|
|
||||||
peoples := []people{
|
|
||||||
{Name: "a", Age: 20},
|
|
||||||
{Name: "b", Age: 10},
|
|
||||||
{Name: "c", Age: 17},
|
|
||||||
{Name: "d", Age: 8},
|
|
||||||
{Name: "e", Age: 28},
|
|
||||||
}
|
|
||||||
comparator := &peopleAgeComparator{}
|
|
||||||
BubbleSort(peoples, comparator)
|
|
||||||
|
|
||||||
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
|
|
||||||
actual := fmt.Sprintf("%v", peoples)
|
|
||||||
|
|
||||||
asssert.Equal(expected, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBubbleSortForIntSlice(t *testing.T) {
|
|
||||||
asssert := internal.NewAssert(t, "TestBubbleSortForIntSlice")
|
|
||||||
numbers := []int{2, 1, 5, 3, 6, 4}
|
|
||||||
comparator := &intComparator{}
|
|
||||||
BubbleSort(numbers, comparator)
|
|
||||||
|
|
||||||
asssert.Equal([]int{1, 2, 3, 4, 5, 6}, numbers)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInsertionSort(t *testing.T) {
|
|
||||||
asssert := internal.NewAssert(t, "TestInsertionSort")
|
|
||||||
|
|
||||||
peoples := []people{
|
|
||||||
{Name: "a", Age: 20},
|
|
||||||
{Name: "b", Age: 10},
|
|
||||||
{Name: "c", Age: 17},
|
|
||||||
{Name: "d", Age: 8},
|
|
||||||
{Name: "e", Age: 28},
|
|
||||||
}
|
|
||||||
comparator := &peopleAgeComparator{}
|
|
||||||
InsertionSort(peoples, comparator)
|
|
||||||
|
|
||||||
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
|
|
||||||
actual := fmt.Sprintf("%v", peoples)
|
|
||||||
|
|
||||||
asssert.Equal(expected, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSelectionSort(t *testing.T) {
|
|
||||||
asssert := internal.NewAssert(t, "TestSelectionSort")
|
|
||||||
|
|
||||||
peoples := []people{
|
|
||||||
{Name: "a", Age: 20},
|
|
||||||
{Name: "b", Age: 10},
|
|
||||||
{Name: "c", Age: 17},
|
|
||||||
{Name: "d", Age: 8},
|
|
||||||
{Name: "e", Age: 28},
|
|
||||||
}
|
|
||||||
comparator := &peopleAgeComparator{}
|
|
||||||
SelectionSort(peoples, comparator)
|
|
||||||
|
|
||||||
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
|
|
||||||
actual := fmt.Sprintf("%v", peoples)
|
|
||||||
|
|
||||||
asssert.Equal(expected, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestShellSort(t *testing.T) {
|
|
||||||
asssert := internal.NewAssert(t, "TestShellSort")
|
|
||||||
|
|
||||||
peoples := []people{
|
|
||||||
{Name: "a", Age: 20},
|
|
||||||
{Name: "b", Age: 10},
|
|
||||||
{Name: "c", Age: 17},
|
|
||||||
{Name: "d", Age: 8},
|
|
||||||
{Name: "e", Age: 28},
|
|
||||||
}
|
|
||||||
comparator := &peopleAgeComparator{}
|
|
||||||
ShellSort(peoples, comparator)
|
|
||||||
|
|
||||||
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
|
|
||||||
actual := fmt.Sprintf("%v", peoples)
|
|
||||||
|
|
||||||
asssert.Equal(expected, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestQuickSort(t *testing.T) {
|
|
||||||
asssert := internal.NewAssert(t, "TestQuickSort")
|
|
||||||
|
|
||||||
peoples := []people{
|
|
||||||
{Name: "a", Age: 20},
|
|
||||||
{Name: "b", Age: 10},
|
|
||||||
{Name: "c", Age: 17},
|
|
||||||
{Name: "d", Age: 8},
|
|
||||||
{Name: "e", Age: 28},
|
|
||||||
}
|
|
||||||
comparator := &peopleAgeComparator{}
|
|
||||||
QuickSort(peoples, 0, len(peoples)-1, comparator)
|
|
||||||
|
|
||||||
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
|
|
||||||
actual := fmt.Sprintf("%v", peoples)
|
|
||||||
|
|
||||||
asssert.Equal(expected, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHeapSort(t *testing.T) {
|
|
||||||
asssert := internal.NewAssert(t, "TestHeapSort")
|
|
||||||
|
|
||||||
peoples := []people{
|
|
||||||
{Name: "a", Age: 20},
|
|
||||||
{Name: "b", Age: 10},
|
|
||||||
{Name: "c", Age: 17},
|
|
||||||
{Name: "d", Age: 8},
|
|
||||||
{Name: "e", Age: 28},
|
|
||||||
}
|
|
||||||
comparator := &peopleAgeComparator{}
|
|
||||||
HeapSort(peoples, comparator)
|
|
||||||
|
|
||||||
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
|
|
||||||
actual := fmt.Sprintf("%v", peoples)
|
|
||||||
|
|
||||||
asssert.Equal(expected, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMergeSort(t *testing.T) {
|
|
||||||
asssert := internal.NewAssert(t, "TestMergeSort")
|
|
||||||
|
|
||||||
peoples := []people{
|
|
||||||
{Name: "a", Age: 20},
|
|
||||||
{Name: "b", Age: 10},
|
|
||||||
{Name: "c", Age: 17},
|
|
||||||
{Name: "d", Age: 8},
|
|
||||||
{Name: "e", Age: 28},
|
|
||||||
}
|
|
||||||
comparator := &peopleAgeComparator{}
|
|
||||||
MergeSort(peoples, comparator)
|
|
||||||
|
|
||||||
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
|
|
||||||
actual := fmt.Sprintf("%v", peoples)
|
|
||||||
|
|
||||||
asssert.Equal(expected, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCountSort(t *testing.T) {
|
|
||||||
asssert := internal.NewAssert(t, "TestCountSort")
|
|
||||||
|
|
||||||
peoples := []people{
|
|
||||||
{Name: "a", Age: 20},
|
|
||||||
{Name: "b", Age: 10},
|
|
||||||
{Name: "c", Age: 17},
|
|
||||||
{Name: "d", Age: 8},
|
|
||||||
{Name: "e", Age: 28},
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
58
compare/compare.go
Normal file
58
compare/compare.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
// Copyright 2023 dudaodong@gmail.com. All rights resulterved.
|
||||||
|
// Use of this source code is governed by MIT license
|
||||||
|
|
||||||
|
// Package compare provides a lightweight comparison function on interface{} type.
|
||||||
|
// reference: https://github.com/stretchr/testify
|
||||||
|
package compare
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
// operator type
|
||||||
|
const (
|
||||||
|
equal = "eq"
|
||||||
|
lessThan = "lt"
|
||||||
|
greaterThan = "gt"
|
||||||
|
lessOrEqual = "le"
|
||||||
|
greaterOrEqual = "ge"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
timeType = reflect.TypeOf(time.Time{})
|
||||||
|
bytesType = reflect.TypeOf([]byte{})
|
||||||
|
)
|
||||||
|
|
||||||
|
// Equal checks if two values are equal or not. (check both type and value)
|
||||||
|
func Equal(left, right interface{}) bool {
|
||||||
|
return compareValue(equal, left, right)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EqualValue checks if two values are equal or not. (check value only)
|
||||||
|
func EqualValue(left, right interface{}) bool {
|
||||||
|
ls, rs := convertor.ToString(left), convertor.ToString(right)
|
||||||
|
return ls == rs
|
||||||
|
}
|
||||||
|
|
||||||
|
// LessThan checks if value `left` less than value `right`.
|
||||||
|
func LessThan(left, right interface{}) bool {
|
||||||
|
return compareValue(lessThan, left, right)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GreaterThan checks if value `left` greater than value `right`.
|
||||||
|
func GreaterThan(left, right interface{}) bool {
|
||||||
|
return compareValue(greaterThan, left, right)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LessOrEqual checks if value `left` less than or equal to value `right`.
|
||||||
|
func LessOrEqual(left, right interface{}) bool {
|
||||||
|
return compareValue(lessOrEqual, left, right)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GreaterOrEqual checks if value `left` greater than or equal to value `right`.
|
||||||
|
func GreaterOrEqual(left, right interface{}) bool {
|
||||||
|
return compareValue(greaterOrEqual, left, right)
|
||||||
|
}
|
||||||
170
compare/compare_example_test.go
Normal file
170
compare/compare_example_test.go
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
package compare
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ExampleEqual() {
|
||||||
|
result1 := Equal(1, 1)
|
||||||
|
result2 := Equal("1", "1")
|
||||||
|
result3 := Equal([]int{1, 2, 3}, []int{1, 2, 3})
|
||||||
|
result4 := Equal(map[int]string{1: "a", 2: "b"}, map[int]string{1: "a", 2: "b"})
|
||||||
|
|
||||||
|
result5 := Equal(1, "1")
|
||||||
|
result6 := Equal(1, int64(1))
|
||||||
|
result7 := Equal([]int{1, 2}, []int{1, 2, 3})
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
fmt.Println(result5)
|
||||||
|
fmt.Println(result6)
|
||||||
|
fmt.Println(result7)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleEqualValue() {
|
||||||
|
result1 := EqualValue(1, 1)
|
||||||
|
result2 := EqualValue(int(1), int64(1))
|
||||||
|
result3 := EqualValue(1, "1")
|
||||||
|
result4 := EqualValue(1, "2")
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleLessThan() {
|
||||||
|
result1 := LessThan(1, 2)
|
||||||
|
result2 := LessThan(1.1, 2.2)
|
||||||
|
result3 := LessThan("a", "b")
|
||||||
|
|
||||||
|
time1 := time.Now()
|
||||||
|
time2 := time1.Add(time.Second)
|
||||||
|
result4 := LessThan(time1, time2)
|
||||||
|
|
||||||
|
result5 := LessThan(2, 1)
|
||||||
|
result6 := LessThan(1, int64(2))
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
fmt.Println(result5)
|
||||||
|
fmt.Println(result6)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleGreaterThan() {
|
||||||
|
result1 := GreaterThan(2, 1)
|
||||||
|
result2 := GreaterThan(2.2, 1.1)
|
||||||
|
result3 := GreaterThan("b", "a")
|
||||||
|
|
||||||
|
time1 := time.Now()
|
||||||
|
time2 := time1.Add(time.Second)
|
||||||
|
result4 := GreaterThan(time2, time1)
|
||||||
|
|
||||||
|
result5 := GreaterThan(1, 2)
|
||||||
|
result6 := GreaterThan(int64(2), 1)
|
||||||
|
result7 := GreaterThan("b", "c")
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
fmt.Println(result5)
|
||||||
|
fmt.Println(result6)
|
||||||
|
fmt.Println(result7)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleLessOrEqual() {
|
||||||
|
result1 := LessOrEqual(1, 1)
|
||||||
|
result2 := LessOrEqual(1.1, 2.2)
|
||||||
|
result3 := LessOrEqual("a", "b")
|
||||||
|
|
||||||
|
time1 := time.Now()
|
||||||
|
time2 := time1.Add(time.Second)
|
||||||
|
result4 := LessOrEqual(time1, time2)
|
||||||
|
|
||||||
|
result5 := LessOrEqual(2, 1)
|
||||||
|
result6 := LessOrEqual(1, int64(2))
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
fmt.Println(result5)
|
||||||
|
fmt.Println(result6)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleGreaterOrEqual() {
|
||||||
|
result1 := GreaterOrEqual(1, 1)
|
||||||
|
result2 := GreaterOrEqual(2.2, 1.1)
|
||||||
|
result3 := GreaterOrEqual("b", "b")
|
||||||
|
|
||||||
|
time1 := time.Now()
|
||||||
|
time2 := time1.Add(time.Second)
|
||||||
|
result4 := GreaterOrEqual(time2, time1)
|
||||||
|
|
||||||
|
result5 := GreaterOrEqual(1, 2)
|
||||||
|
result6 := GreaterOrEqual(int64(2), 1)
|
||||||
|
result7 := GreaterOrEqual("b", "c")
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
fmt.Println(result5)
|
||||||
|
fmt.Println(result6)
|
||||||
|
fmt.Println(result7)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
323
compare/compare_internal.go
Normal file
323
compare/compare_internal.go
Normal file
@@ -0,0 +1,323 @@
|
|||||||
|
package compare
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"reflect"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func compareValue(operator string, left, right interface{}) bool {
|
||||||
|
leftType, rightType := reflect.TypeOf(left), reflect.TypeOf(right)
|
||||||
|
|
||||||
|
if leftType.Kind() != rightType.Kind() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
switch leftType.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||||
|
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
|
||||||
|
reflect.Float32, reflect.Float64, reflect.Bool, reflect.String:
|
||||||
|
return compareBasicValue(operator, left, right)
|
||||||
|
|
||||||
|
case reflect.Struct, reflect.Slice, reflect.Map:
|
||||||
|
return compareRefValue(operator, left, right, leftType.Kind())
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func compareRefValue(operator string, leftObj, rightObj interface{}, kind reflect.Kind) bool {
|
||||||
|
leftVal, rightVal := reflect.ValueOf(leftObj), reflect.ValueOf(rightObj)
|
||||||
|
|
||||||
|
switch kind {
|
||||||
|
case reflect.Struct:
|
||||||
|
|
||||||
|
// compare time
|
||||||
|
if leftVal.CanConvert(timeType) {
|
||||||
|
timeObj1, ok := leftObj.(time.Time)
|
||||||
|
if !ok {
|
||||||
|
timeObj1 = leftVal.Convert(timeType).Interface().(time.Time)
|
||||||
|
}
|
||||||
|
|
||||||
|
timeObj2, ok := rightObj.(time.Time)
|
||||||
|
if !ok {
|
||||||
|
timeObj2 = rightVal.Convert(timeType).Interface().(time.Time)
|
||||||
|
}
|
||||||
|
|
||||||
|
return compareBasicValue(operator, timeObj1.UnixNano(), timeObj2.UnixNano())
|
||||||
|
}
|
||||||
|
|
||||||
|
// for other struct type, only process equal operator
|
||||||
|
switch operator {
|
||||||
|
case equal:
|
||||||
|
return objectsAreEqualValues(leftObj, rightObj)
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Slice:
|
||||||
|
// compare []byte
|
||||||
|
if leftVal.CanConvert(bytesType) {
|
||||||
|
bytesObj1, ok := leftObj.([]byte)
|
||||||
|
if !ok {
|
||||||
|
bytesObj1 = leftVal.Convert(bytesType).Interface().([]byte)
|
||||||
|
}
|
||||||
|
bytesObj2, ok := rightObj.([]byte)
|
||||||
|
if !ok {
|
||||||
|
bytesObj2 = rightVal.Convert(bytesType).Interface().([]byte)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch operator {
|
||||||
|
case equal:
|
||||||
|
if bytes.Compare(bytesObj1, bytesObj2) == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case lessThan:
|
||||||
|
if bytes.Compare(bytesObj1, bytesObj2) == -1 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case greaterThan:
|
||||||
|
if bytes.Compare(bytesObj1, bytesObj2) == 1 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case lessOrEqual:
|
||||||
|
if bytes.Compare(bytesObj1, bytesObj2) <= 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case greaterOrEqual:
|
||||||
|
if bytes.Compare(bytesObj1, bytesObj2) >= 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// for other type slice, only process equal operator
|
||||||
|
switch operator {
|
||||||
|
case equal:
|
||||||
|
return reflect.DeepEqual(leftObj, rightObj)
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Map:
|
||||||
|
// only process equal operator
|
||||||
|
switch operator {
|
||||||
|
case equal:
|
||||||
|
return reflect.DeepEqual(leftObj, rightObj)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func objectsAreEqualValues(expected, actual interface{}) bool {
|
||||||
|
if objectsAreEqual(expected, actual) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
actualType := reflect.TypeOf(actual)
|
||||||
|
if actualType == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
expectedValue := reflect.ValueOf(expected)
|
||||||
|
if expectedValue.IsValid() && expectedValue.Type().ConvertibleTo(actualType) {
|
||||||
|
// Attempt comparison after type conversion
|
||||||
|
return reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func objectsAreEqual(expected, actual interface{}) bool {
|
||||||
|
if expected == nil || actual == nil {
|
||||||
|
return expected == actual
|
||||||
|
}
|
||||||
|
|
||||||
|
exp, ok := expected.([]byte)
|
||||||
|
if !ok {
|
||||||
|
return reflect.DeepEqual(expected, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
act, ok := actual.([]byte)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if exp == nil || act == nil {
|
||||||
|
return exp == nil && act == nil
|
||||||
|
}
|
||||||
|
return bytes.Equal(exp, act)
|
||||||
|
}
|
||||||
|
|
||||||
|
// compareBasic compare basic value: integer, float, string, bool
|
||||||
|
func compareBasicValue(operator string, leftValue, rightValue interface{}) bool {
|
||||||
|
if leftValue == nil && rightValue == nil && operator == equal {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch leftVal := leftValue.(type) {
|
||||||
|
case json.Number:
|
||||||
|
if left, err := leftVal.Float64(); err == nil {
|
||||||
|
switch rightVal := rightValue.(type) {
|
||||||
|
case json.Number:
|
||||||
|
if right, err := rightVal.Float64(); err == nil {
|
||||||
|
switch operator {
|
||||||
|
case equal:
|
||||||
|
if left == right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case lessThan:
|
||||||
|
if left < right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case greaterThan:
|
||||||
|
if left > right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case lessOrEqual:
|
||||||
|
if left <= right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case greaterOrEqual:
|
||||||
|
if left >= right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
case float32, float64, int, uint, int8, uint8, int16, uint16, int32, uint32, int64, uint64:
|
||||||
|
right, err := convertor.ToFloat(rightValue)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
switch operator {
|
||||||
|
case equal:
|
||||||
|
if left == right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case lessThan:
|
||||||
|
if left < right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case greaterThan:
|
||||||
|
if left > right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case lessOrEqual:
|
||||||
|
if left <= right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case greaterOrEqual:
|
||||||
|
if left >= right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
case float32, float64, int, uint, int8, uint8, int16, uint16, int32, uint32, int64, uint64:
|
||||||
|
left, err := convertor.ToFloat(leftValue)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
switch rightVal := rightValue.(type) {
|
||||||
|
case json.Number:
|
||||||
|
if right, err := rightVal.Float64(); err == nil {
|
||||||
|
switch operator {
|
||||||
|
case equal:
|
||||||
|
if left == right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case lessThan:
|
||||||
|
if left < right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case greaterThan:
|
||||||
|
if left > right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case lessOrEqual:
|
||||||
|
if left <= right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case greaterOrEqual:
|
||||||
|
if left >= right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case float32, float64, int, uint, int8, uint8, int16, uint16, int32, uint32, int64, uint64:
|
||||||
|
right, err := convertor.ToFloat(rightValue)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
switch operator {
|
||||||
|
case equal:
|
||||||
|
if left == right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case lessThan:
|
||||||
|
if left < right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case greaterThan:
|
||||||
|
if left > right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case lessOrEqual:
|
||||||
|
if left <= right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case greaterOrEqual:
|
||||||
|
if left >= right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case string:
|
||||||
|
left := leftVal
|
||||||
|
switch right := rightValue.(type) {
|
||||||
|
case string:
|
||||||
|
switch operator {
|
||||||
|
case equal:
|
||||||
|
if left == right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case lessThan:
|
||||||
|
if left < right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case greaterThan:
|
||||||
|
if left > right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case lessOrEqual:
|
||||||
|
if left <= right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case greaterOrEqual:
|
||||||
|
if left >= right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case bool:
|
||||||
|
left := leftVal
|
||||||
|
switch right := rightValue.(type) {
|
||||||
|
case bool:
|
||||||
|
switch operator {
|
||||||
|
case equal:
|
||||||
|
if left == right {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
134
compare/compare_test.go
Normal file
134
compare/compare_test.go
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
package compare
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestEqual(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestEqual")
|
||||||
|
|
||||||
|
assert.Equal(true, Equal(1, 1))
|
||||||
|
assert.Equal(true, Equal(int64(1), int64(1)))
|
||||||
|
assert.Equal(true, Equal("a", "a"))
|
||||||
|
assert.Equal(true, Equal(true, true))
|
||||||
|
assert.Equal(true, Equal([]int{1, 2, 3}, []int{1, 2, 3}))
|
||||||
|
assert.Equal(true, Equal(map[int]string{1: "a", 2: "b"}, map[int]string{1: "a", 2: "b"}))
|
||||||
|
|
||||||
|
assert.Equal(false, Equal(1, 2))
|
||||||
|
assert.Equal(false, Equal(1, int64(1)))
|
||||||
|
assert.Equal(false, Equal("a", "b"))
|
||||||
|
assert.Equal(false, Equal(true, false))
|
||||||
|
assert.Equal(false, Equal([]int{1, 2}, []int{1, 2, 3}))
|
||||||
|
assert.Equal(false, Equal(map[int]string{1: "a", 2: "b"}, map[int]string{1: "a"}))
|
||||||
|
|
||||||
|
time1 := time.Now()
|
||||||
|
time2 := time1.Add(time.Second)
|
||||||
|
time3 := time1.Add(time.Second)
|
||||||
|
|
||||||
|
assert.Equal(false, Equal(time1, time2))
|
||||||
|
assert.Equal(true, Equal(time2, time3))
|
||||||
|
|
||||||
|
st1 := struct {
|
||||||
|
A string
|
||||||
|
B string
|
||||||
|
}{
|
||||||
|
A: "a",
|
||||||
|
B: "b",
|
||||||
|
}
|
||||||
|
|
||||||
|
st2 := struct {
|
||||||
|
A string
|
||||||
|
B string
|
||||||
|
}{
|
||||||
|
A: "a",
|
||||||
|
B: "b",
|
||||||
|
}
|
||||||
|
|
||||||
|
st3 := struct {
|
||||||
|
A string
|
||||||
|
B string
|
||||||
|
}{
|
||||||
|
A: "a1",
|
||||||
|
B: "b",
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(true, Equal(st1, st2))
|
||||||
|
assert.Equal(false, Equal(st1, st3))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEqualValue(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestEqualValue")
|
||||||
|
|
||||||
|
assert.Equal(true, EqualValue(1, 1))
|
||||||
|
assert.Equal(true, EqualValue(int(1), int64(1)))
|
||||||
|
assert.Equal(true, EqualValue(1, "1"))
|
||||||
|
|
||||||
|
assert.Equal(false, EqualValue(1, "2"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLessThan(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestLessThan")
|
||||||
|
|
||||||
|
assert.Equal(true, LessThan(1, 2))
|
||||||
|
assert.Equal(true, LessThan(1.1, 2.2))
|
||||||
|
assert.Equal(true, LessThan("a", "b"))
|
||||||
|
|
||||||
|
time1 := time.Now()
|
||||||
|
time2 := time1.Add(time.Second)
|
||||||
|
assert.Equal(true, LessThan(time1, time2))
|
||||||
|
|
||||||
|
assert.Equal(false, LessThan(1, 1))
|
||||||
|
assert.Equal(false, LessThan(1, int64(1)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGreaterThan(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestGreaterThan")
|
||||||
|
|
||||||
|
assert.Equal(true, GreaterThan(2, 1))
|
||||||
|
assert.Equal(true, GreaterThan(2.2, 1.1))
|
||||||
|
assert.Equal(true, GreaterThan("b", "a"))
|
||||||
|
|
||||||
|
time1 := time.Now()
|
||||||
|
time2 := time1.Add(time.Second)
|
||||||
|
assert.Equal(true, GreaterThan(time2, time1))
|
||||||
|
|
||||||
|
assert.Equal(false, GreaterThan(1, 2))
|
||||||
|
assert.Equal(false, GreaterThan(int64(2), 1))
|
||||||
|
assert.Equal(false, GreaterThan("b", "c"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLessOrEqual(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestLessOrEqual")
|
||||||
|
|
||||||
|
assert.Equal(true, LessOrEqual(1, 2))
|
||||||
|
assert.Equal(true, LessOrEqual(1, 1))
|
||||||
|
assert.Equal(true, LessOrEqual(1.1, 2.2))
|
||||||
|
assert.Equal(true, LessOrEqual("a", "b"))
|
||||||
|
|
||||||
|
time1 := time.Now()
|
||||||
|
time2 := time1.Add(time.Second)
|
||||||
|
assert.Equal(true, LessOrEqual(time1, time2))
|
||||||
|
|
||||||
|
assert.Equal(false, LessOrEqual(2, 1))
|
||||||
|
assert.Equal(false, LessOrEqual(1, int64(2)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGreaterOrEqual(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestGreaterThan")
|
||||||
|
|
||||||
|
assert.Equal(true, GreaterOrEqual(2, 1))
|
||||||
|
assert.Equal(true, GreaterOrEqual(1, 1))
|
||||||
|
assert.Equal(true, GreaterOrEqual(2.2, 1.1))
|
||||||
|
assert.Equal(true, GreaterOrEqual("b", "b"))
|
||||||
|
|
||||||
|
time1 := time.Now()
|
||||||
|
time2 := time1.Add(time.Second)
|
||||||
|
assert.Equal(true, GreaterOrEqual(time2, time1))
|
||||||
|
|
||||||
|
assert.Equal(false, GreaterOrEqual(1, 2))
|
||||||
|
assert.Equal(false, GreaterOrEqual(int64(2), 1))
|
||||||
|
assert.Equal(false, GreaterOrEqual("b", "c"))
|
||||||
|
}
|
||||||
@@ -7,13 +7,19 @@ package convertor
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"encoding/gob"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"math"
|
"math"
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/text/encoding/simplifiedchinese"
|
||||||
|
"golang.org/x/text/transform"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ToBool convert string to a boolean
|
// ToBool convert string to a boolean
|
||||||
@@ -22,7 +28,7 @@ func ToBool(s string) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ToBytes convert interface to bytes
|
// ToBytes convert interface to bytes
|
||||||
func ToBytes(value any) ([]byte, error) {
|
func ToBytes(value interface{}) ([]byte, error) {
|
||||||
v := reflect.ValueOf(value)
|
v := reflect.ValueOf(value)
|
||||||
|
|
||||||
switch value.(type) {
|
switch value.(type) {
|
||||||
@@ -75,39 +81,51 @@ func ToChar(s string) []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ToString convert value to string
|
// ToString convert value to string
|
||||||
func ToString(value any) string {
|
func ToString(value interface{}) string {
|
||||||
res := ""
|
|
||||||
if value == nil {
|
if value == nil {
|
||||||
return res
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
v := reflect.ValueOf(value)
|
switch val := value.(type) {
|
||||||
|
case float32:
|
||||||
switch value.(type) {
|
return strconv.FormatFloat(float64(val), 'f', -1, 32)
|
||||||
case float32, float64:
|
case float64:
|
||||||
res = strconv.FormatFloat(v.Float(), 'f', -1, 64)
|
return strconv.FormatFloat(val, 'f', -1, 64)
|
||||||
return res
|
case int:
|
||||||
case int, int8, int16, int32, int64:
|
return strconv.FormatInt(int64(val), 10)
|
||||||
res = strconv.FormatInt(v.Int(), 10)
|
case int8:
|
||||||
return res
|
return strconv.FormatInt(int64(val), 10)
|
||||||
case uint, uint8, uint16, uint32, uint64:
|
case int16:
|
||||||
res = strconv.FormatUint(v.Uint(), 10)
|
return strconv.FormatInt(int64(val), 10)
|
||||||
return res
|
case int32:
|
||||||
|
return strconv.FormatInt(int64(val), 10)
|
||||||
|
case int64:
|
||||||
|
return strconv.FormatInt(val, 10)
|
||||||
|
case uint:
|
||||||
|
return strconv.FormatUint(uint64(val), 10)
|
||||||
|
case uint8:
|
||||||
|
return strconv.FormatUint(uint64(val), 10)
|
||||||
|
case uint16:
|
||||||
|
return strconv.FormatUint(uint64(val), 10)
|
||||||
|
case uint32:
|
||||||
|
return strconv.FormatUint(uint64(val), 10)
|
||||||
|
case uint64:
|
||||||
|
return strconv.FormatUint(val, 10)
|
||||||
case string:
|
case string:
|
||||||
res = v.String()
|
return val
|
||||||
return res
|
|
||||||
case []byte:
|
case []byte:
|
||||||
res = string(v.Bytes())
|
return string(val)
|
||||||
return res
|
|
||||||
default:
|
default:
|
||||||
newValue, _ := json.Marshal(value)
|
b, err := json.Marshal(val)
|
||||||
res = string(newValue)
|
if err != nil {
|
||||||
return res
|
return ""
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToJson convert value to a valid json string
|
// ToJson convert value to a valid json string
|
||||||
func ToJson(value any) (string, error) {
|
func ToJson(value interface{}) (string, error) {
|
||||||
res, err := json.Marshal(value)
|
res, err := json.Marshal(value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@@ -117,7 +135,7 @@ func ToJson(value any) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ToFloat convert value to a float64, if input is not a float return 0.0 and error
|
// ToFloat convert value to a float64, if input is not a float return 0.0 and error
|
||||||
func ToFloat(value any) (float64, error) {
|
func ToFloat(value interface{}) (float64, error) {
|
||||||
v := reflect.ValueOf(value)
|
v := reflect.ValueOf(value)
|
||||||
|
|
||||||
res := 0.0
|
res := 0.0
|
||||||
@@ -144,7 +162,7 @@ func ToFloat(value any) (float64, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ToInt convert value to a int64, if input is not a numeric format return 0 and error
|
// ToInt convert value to a int64, if input is not a numeric format return 0 and error
|
||||||
func ToInt(value any) (int64, error) {
|
func ToInt(value interface{}) (int64, error) {
|
||||||
v := reflect.ValueOf(value)
|
v := reflect.ValueOf(value)
|
||||||
|
|
||||||
var res int64
|
var res int64
|
||||||
@@ -172,7 +190,7 @@ func ToInt(value any) (int64, error) {
|
|||||||
|
|
||||||
// StructToMap convert struct to map, only convert exported struct field
|
// StructToMap convert struct to map, only convert exported struct field
|
||||||
// map key is specified same as struct field tag `json` value
|
// map key is specified same as struct field tag `json` value
|
||||||
func StructToMap(value any) (map[string]any, error) {
|
func StructToMap(value interface{}) (map[string]interface{}, error) {
|
||||||
v := reflect.ValueOf(value)
|
v := reflect.ValueOf(value)
|
||||||
t := reflect.TypeOf(value)
|
t := reflect.TypeOf(value)
|
||||||
|
|
||||||
@@ -183,7 +201,7 @@ func StructToMap(value any) (map[string]any, error) {
|
|||||||
return nil, fmt.Errorf("data type %T not support, shuld be struct or pointer to struct", value)
|
return nil, fmt.Errorf("data type %T not support, shuld be struct or pointer to struct", value)
|
||||||
}
|
}
|
||||||
|
|
||||||
res := make(map[string]any)
|
res := make(map[string]interface{})
|
||||||
|
|
||||||
fieldNum := t.NumField()
|
fieldNum := t.NumField()
|
||||||
pattern := `^[A-Z]`
|
pattern := `^[A-Z]`
|
||||||
@@ -229,3 +247,160 @@ func ColorRGBToHex(red, green, blue int) string {
|
|||||||
|
|
||||||
return "#" + r + g + b
|
return "#" + r + g + b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToChannel convert a array of elements to a read-only channels
|
||||||
|
func ToChannel(array []interface{}) <-chan interface{} {
|
||||||
|
ch := make(chan interface{})
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for _, item := range array {
|
||||||
|
ch <- item
|
||||||
|
}
|
||||||
|
close(ch)
|
||||||
|
}()
|
||||||
|
|
||||||
|
return ch
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncodeByte encode data to byte
|
||||||
|
func EncodeByte(data interface{}) ([]byte, error) {
|
||||||
|
buffer := bytes.NewBuffer(nil)
|
||||||
|
encoder := gob.NewEncoder(buffer)
|
||||||
|
err := encoder.Encode(data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return buffer.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeByte decode byte data to target object
|
||||||
|
func DecodeByte(data []byte, target interface{}) error {
|
||||||
|
buffer := bytes.NewBuffer(data)
|
||||||
|
decoder := gob.NewDecoder(buffer)
|
||||||
|
return decoder.Decode(target)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepClone creates a deep copy of passed item.
|
||||||
|
// can't clone unexported field of struct
|
||||||
|
func DeepClone(src interface{}) interface{} {
|
||||||
|
c := cloner{
|
||||||
|
ptrs: map[reflect.Type]map[uintptr]reflect.Value{},
|
||||||
|
}
|
||||||
|
result := c.clone(reflect.ValueOf(src))
|
||||||
|
if result.Kind() == reflect.Invalid {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
// // CopyProperties copies each field from the source into the destination. It recursively copies struct pointers and interfaces that contain struct pointers.
|
||||||
|
// func CopyProperties(dst, src interface{}) (err error) {
|
||||||
|
// defer func() {
|
||||||
|
// if e := recover(); e != nil {
|
||||||
|
// err = errors.New(fmt.Sprintf("%v", e))
|
||||||
|
// }
|
||||||
|
// }()
|
||||||
|
|
||||||
|
// dstType, dstValue := reflect.TypeOf(dst), reflect.ValueOf(dst)
|
||||||
|
// srcType, srcValue := reflect.TypeOf(src), reflect.ValueOf(src)
|
||||||
|
|
||||||
|
// if dstType.Kind() != reflect.Ptr || dstType.Elem().Kind() != reflect.Struct {
|
||||||
|
// return errors.New("CopyProperties: param dst should be struct pointer")
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if srcType.Kind() == reflect.Ptr {
|
||||||
|
// srcType, srcValue = srcType.Elem(), srcValue.Elem()
|
||||||
|
// }
|
||||||
|
// if srcType.Kind() != reflect.Struct {
|
||||||
|
// return errors.New("CopyProperties: param src should be a struct or struct pointer")
|
||||||
|
// }
|
||||||
|
|
||||||
|
// dstType, dstValue = dstType.Elem(), dstValue.Elem()
|
||||||
|
|
||||||
|
// propertyNums := dstType.NumField()
|
||||||
|
|
||||||
|
// for i := 0; i < propertyNums; i++ {
|
||||||
|
// property := dstType.Field(i)
|
||||||
|
// propertyValue := srcValue.FieldByName(property.Name)
|
||||||
|
|
||||||
|
// if !propertyValue.IsValid() || property.Type != propertyValue.Type() {
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if dstValue.Field(i).CanSet() {
|
||||||
|
// dstValue.Field(i).Set(propertyValue)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// CopyProperties copies each field from the source into the destination. It recursively copies struct pointers and interfaces that contain struct pointers.
|
||||||
|
// use json.Marshal/Unmarshal, so json tag should be set for fields of dst and src struct.
|
||||||
|
func CopyProperties(dst, src interface{}) error {
|
||||||
|
dstType, srcType := reflect.TypeOf(dst), reflect.TypeOf(src)
|
||||||
|
|
||||||
|
if dstType.Kind() != reflect.Ptr || dstType.Elem().Kind() != reflect.Struct {
|
||||||
|
return errors.New("CopyProperties: parameter dst should be struct pointer")
|
||||||
|
}
|
||||||
|
|
||||||
|
if srcType.Kind() == reflect.Ptr {
|
||||||
|
srcType = srcType.Elem()
|
||||||
|
}
|
||||||
|
if srcType.Kind() != reflect.Struct {
|
||||||
|
return errors.New("CopyProperties: parameter src should be a struct or struct pointer")
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes, err := json.Marshal(src)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("CopyProperties: unable to marshal src: %s", err)
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(bytes, dst)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("CopyProperties: unable to unmarshal into dst: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToInterface converts reflect value to its interface type.
|
||||||
|
func ToInterface(v reflect.Value) (value interface{}, ok bool) {
|
||||||
|
if v.IsValid() && v.CanInterface() {
|
||||||
|
return v.Interface(), true
|
||||||
|
}
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Bool:
|
||||||
|
return v.Bool(), true
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return v.Int(), true
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
return v.Uint(), true
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return v.Float(), true
|
||||||
|
case reflect.Complex64, reflect.Complex128:
|
||||||
|
return v.Complex(), true
|
||||||
|
case reflect.String:
|
||||||
|
return v.String(), true
|
||||||
|
case reflect.Ptr:
|
||||||
|
return ToInterface(v.Elem())
|
||||||
|
case reflect.Interface:
|
||||||
|
return ToInterface(v.Elem())
|
||||||
|
default:
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utf8ToGbk convert utf8 encoding data to GBK encoding data.
|
||||||
|
func Utf8ToGbk(bs []byte) ([]byte, error) {
|
||||||
|
r := transform.NewReader(bytes.NewReader(bs), simplifiedchinese.GBK.NewEncoder())
|
||||||
|
b, err := io.ReadAll(r)
|
||||||
|
return b, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GbkToUtf8 convert GBK encoding data to utf8 encoding data.
|
||||||
|
func GbkToUtf8(bs []byte) ([]byte, error) {
|
||||||
|
r := transform.NewReader(bytes.NewReader(bs), simplifiedchinese.GBK.NewDecoder())
|
||||||
|
b, err := io.ReadAll(r)
|
||||||
|
return b, err
|
||||||
|
}
|
||||||
|
|||||||
216
convertor/convertor_internal.go
Normal file
216
convertor/convertor_internal.go
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
// Copyright 2023 dudaodong@gmail.com. All rights reserved.
|
||||||
|
// Use of this source code is governed by MIT license
|
||||||
|
|
||||||
|
// Package convertor implements some functions to convert data.
|
||||||
|
package convertor
|
||||||
|
|
||||||
|
import "reflect"
|
||||||
|
|
||||||
|
type cloner struct {
|
||||||
|
ptrs map[reflect.Type]map[uintptr]reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
// clone return a duplicate of passed item.
|
||||||
|
func (c *cloner) clone(v reflect.Value) reflect.Value {
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Invalid:
|
||||||
|
return reflect.ValueOf(nil)
|
||||||
|
|
||||||
|
// bool
|
||||||
|
case reflect.Bool:
|
||||||
|
return reflect.ValueOf(v.Bool())
|
||||||
|
|
||||||
|
//int
|
||||||
|
case reflect.Int:
|
||||||
|
return reflect.ValueOf(int(v.Int()))
|
||||||
|
case reflect.Int8:
|
||||||
|
return reflect.ValueOf(int8(v.Int()))
|
||||||
|
case reflect.Int16:
|
||||||
|
return reflect.ValueOf(int16(v.Int()))
|
||||||
|
case reflect.Int32:
|
||||||
|
return reflect.ValueOf(int32(v.Int()))
|
||||||
|
case reflect.Int64:
|
||||||
|
return reflect.ValueOf(v.Int())
|
||||||
|
|
||||||
|
// uint
|
||||||
|
case reflect.Uint:
|
||||||
|
return reflect.ValueOf(uint(v.Uint()))
|
||||||
|
case reflect.Uint8:
|
||||||
|
return reflect.ValueOf(uint8(v.Uint()))
|
||||||
|
case reflect.Uint16:
|
||||||
|
return reflect.ValueOf(uint16(v.Uint()))
|
||||||
|
case reflect.Uint32:
|
||||||
|
return reflect.ValueOf(uint32(v.Uint()))
|
||||||
|
case reflect.Uint64:
|
||||||
|
return reflect.ValueOf(v.Uint())
|
||||||
|
|
||||||
|
// float
|
||||||
|
case reflect.Float32:
|
||||||
|
return reflect.ValueOf(float32(v.Float()))
|
||||||
|
case reflect.Float64:
|
||||||
|
return reflect.ValueOf(v.Float())
|
||||||
|
|
||||||
|
// complex
|
||||||
|
case reflect.Complex64:
|
||||||
|
return reflect.ValueOf(complex64(v.Complex()))
|
||||||
|
case reflect.Complex128:
|
||||||
|
return reflect.ValueOf(v.Complex())
|
||||||
|
|
||||||
|
// string
|
||||||
|
case reflect.String:
|
||||||
|
return reflect.ValueOf(v.String())
|
||||||
|
|
||||||
|
// array
|
||||||
|
case reflect.Array, reflect.Slice:
|
||||||
|
return c.cloneArray(v)
|
||||||
|
|
||||||
|
// map
|
||||||
|
case reflect.Map:
|
||||||
|
return c.cloneMap(v)
|
||||||
|
|
||||||
|
// Ptr
|
||||||
|
case reflect.Ptr:
|
||||||
|
return c.clonePtr(v)
|
||||||
|
|
||||||
|
// struct
|
||||||
|
case reflect.Struct:
|
||||||
|
return c.cloneStruct(v)
|
||||||
|
|
||||||
|
// func
|
||||||
|
case reflect.Func:
|
||||||
|
return v
|
||||||
|
|
||||||
|
// interface
|
||||||
|
case reflect.Interface:
|
||||||
|
return c.clone(v.Elem())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return reflect.Zero(v.Type())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cloner) cloneArray(v reflect.Value) reflect.Value {
|
||||||
|
if v.IsNil() {
|
||||||
|
return reflect.Zero(v.Type())
|
||||||
|
}
|
||||||
|
|
||||||
|
arr := reflect.MakeSlice(v.Type(), v.Len(), v.Len())
|
||||||
|
|
||||||
|
for i := 0; i < v.Len(); i++ {
|
||||||
|
val := c.clone(v.Index(i))
|
||||||
|
|
||||||
|
if val.IsValid() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
item := arr.Index(i)
|
||||||
|
if !item.CanSet() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
item.Set(val.Convert(item.Type()))
|
||||||
|
}
|
||||||
|
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cloner) cloneMap(v reflect.Value) reflect.Value {
|
||||||
|
if v.IsNil() {
|
||||||
|
return reflect.Zero(v.Type())
|
||||||
|
}
|
||||||
|
|
||||||
|
clonedMap := reflect.MakeMap(v.Type())
|
||||||
|
|
||||||
|
for _, key := range v.MapKeys() {
|
||||||
|
value := v.MapIndex(key)
|
||||||
|
clonedKey := c.clone(key)
|
||||||
|
clonedValue := c.clone(value)
|
||||||
|
|
||||||
|
if !isNillable(clonedKey) || !clonedKey.IsNil() {
|
||||||
|
clonedKey = clonedKey.Convert(key.Type())
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isNillable(clonedValue) || !clonedValue.IsNil()) && clonedValue.IsValid() {
|
||||||
|
clonedValue = clonedValue.Convert(value.Type())
|
||||||
|
}
|
||||||
|
|
||||||
|
if !clonedValue.IsValid() {
|
||||||
|
clonedValue = reflect.Zero(clonedMap.Type().Elem())
|
||||||
|
}
|
||||||
|
|
||||||
|
clonedMap.SetMapIndex(clonedKey, clonedValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
return clonedMap
|
||||||
|
}
|
||||||
|
|
||||||
|
func isNillable(v reflect.Value) bool {
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Chan, reflect.Interface, reflect.Ptr, reflect.Func:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cloner) clonePtr(v reflect.Value) reflect.Value {
|
||||||
|
if v.IsNil() {
|
||||||
|
return reflect.Zero(v.Type())
|
||||||
|
}
|
||||||
|
|
||||||
|
var newVal reflect.Value
|
||||||
|
|
||||||
|
if v.Elem().CanAddr() {
|
||||||
|
ptrs, exists := c.ptrs[v.Type()]
|
||||||
|
if exists {
|
||||||
|
if newVal, exists := ptrs[v.Elem().UnsafeAddr()]; exists {
|
||||||
|
return newVal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newVal = c.clone(v.Elem())
|
||||||
|
|
||||||
|
if v.Elem().CanAddr() {
|
||||||
|
ptrs, exists := c.ptrs[v.Type()]
|
||||||
|
if exists {
|
||||||
|
if newVal, exists := ptrs[v.Elem().UnsafeAddr()]; exists {
|
||||||
|
return newVal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clonedPtr := reflect.New(newVal.Type())
|
||||||
|
clonedPtr.Elem().Set(newVal)
|
||||||
|
|
||||||
|
return clonedPtr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cloner) cloneStruct(v reflect.Value) reflect.Value {
|
||||||
|
clonedStructPtr := reflect.New(v.Type())
|
||||||
|
clonedStruct := clonedStructPtr.Elem()
|
||||||
|
|
||||||
|
if v.CanAddr() {
|
||||||
|
ptrs := c.ptrs[clonedStructPtr.Type()]
|
||||||
|
if ptrs == nil {
|
||||||
|
ptrs = make(map[uintptr]reflect.Value)
|
||||||
|
c.ptrs[clonedStructPtr.Type()] = ptrs
|
||||||
|
}
|
||||||
|
ptrs[v.UnsafeAddr()] = clonedStructPtr
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < v.NumField(); i++ {
|
||||||
|
newStructValue := clonedStruct.Field(i)
|
||||||
|
if !newStructValue.CanSet() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
clonedVal := c.clone(v.Field(i))
|
||||||
|
if !clonedVal.IsValid() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
newStructValue.Set(clonedVal.Convert(newStructValue.Type()))
|
||||||
|
}
|
||||||
|
|
||||||
|
return clonedStruct
|
||||||
|
}
|
||||||
@@ -2,9 +2,12 @@ package convertor
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/duke-git/lancet/v2/internal"
|
"github.com/duke-git/lancet/internal"
|
||||||
|
"github.com/duke-git/lancet/validator"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestToChar(t *testing.T) {
|
func TestToChar(t *testing.T) {
|
||||||
@@ -36,7 +39,7 @@ func TestToBool(t *testing.T) {
|
|||||||
func TestToBytes(t *testing.T) {
|
func TestToBytes(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestToBytes")
|
assert := internal.NewAssert(t, "TestToBytes")
|
||||||
|
|
||||||
cases := []any{
|
cases := []interface{}{
|
||||||
0,
|
0,
|
||||||
false,
|
false,
|
||||||
"1",
|
"1",
|
||||||
@@ -62,7 +65,7 @@ func TestToBytes(t *testing.T) {
|
|||||||
func TestToInt(t *testing.T) {
|
func TestToInt(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestToInt")
|
assert := internal.NewAssert(t, "TestToInt")
|
||||||
|
|
||||||
cases := []any{"123", "-123", 123,
|
cases := []interface{}{"123", "-123", 123,
|
||||||
uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
|
uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
|
||||||
float32(12.3), float64(12.3),
|
float32(12.3), float64(12.3),
|
||||||
"abc", false, "111111111111111111111111111111111111111"}
|
"abc", false, "111111111111111111111111111111111111111"}
|
||||||
@@ -78,7 +81,7 @@ func TestToInt(t *testing.T) {
|
|||||||
func TestToFloat(t *testing.T) {
|
func TestToFloat(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestToFloat")
|
assert := internal.NewAssert(t, "TestToFloat")
|
||||||
|
|
||||||
cases := []any{
|
cases := []interface{}{
|
||||||
"", "-1", "-.11", "1.23e3", ".123e10", "abc",
|
"", "-1", "-.11", "1.23e3", ".123e10", "abc",
|
||||||
int(0), int8(1), int16(-1), int32(123), int64(123),
|
int(0), int8(1), int16(-1), int32(123), int64(123),
|
||||||
uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
|
uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
|
||||||
@@ -106,7 +109,7 @@ func TestToString(t *testing.T) {
|
|||||||
}
|
}
|
||||||
aStruct := TestStruct{Name: "TestStruct"}
|
aStruct := TestStruct{Name: "TestStruct"}
|
||||||
|
|
||||||
cases := []any{
|
cases := []interface{}{
|
||||||
"", nil,
|
"", nil,
|
||||||
int(0), int8(1), int16(-1), int32(123), int64(123),
|
int(0), int8(1), int16(-1), int32(123), int64(123),
|
||||||
uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
|
uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
|
||||||
@@ -118,7 +121,7 @@ func TestToString(t *testing.T) {
|
|||||||
"", "",
|
"", "",
|
||||||
"0", "1", "-1",
|
"0", "1", "-1",
|
||||||
"123", "123", "123", "123", "123", "123", "123",
|
"123", "123", "123", "123", "123", "123", "123",
|
||||||
"12.3", "12.300000190734863",
|
"12.3", "12.3",
|
||||||
"true", "false",
|
"true", "false",
|
||||||
"[1,2,3]", "{\"a\":1,\"b\":2,\"c\":3}", "{\"Name\":\"TestStruct\"}", "hello"}
|
"[1,2,3]", "{\"a\":1,\"b\":2,\"c\":3}", "{\"Name\":\"TestStruct\"}", "hello"}
|
||||||
|
|
||||||
@@ -154,7 +157,7 @@ func TestStructToMap(t *testing.T) {
|
|||||||
100,
|
100,
|
||||||
}
|
}
|
||||||
pm, _ := StructToMap(p)
|
pm, _ := StructToMap(p)
|
||||||
var expected = map[string]any{"name": "test"}
|
var expected = map[string]interface{}{"name": "test"}
|
||||||
assert.Equal(expected, pm)
|
assert.Equal(expected, pm)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,3 +181,185 @@ func TestColorRGBToHex(t *testing.T) {
|
|||||||
assert := internal.NewAssert(t, "TestColorRGBToHex")
|
assert := internal.NewAssert(t, "TestColorRGBToHex")
|
||||||
assert.Equal(expected, colorHex)
|
assert.Equal(expected, colorHex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestToChannel(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestToChannel")
|
||||||
|
|
||||||
|
ch := ToChannel([]interface{}{1, 2, 3})
|
||||||
|
val1, _ := <-ch
|
||||||
|
assert.Equal(1, val1)
|
||||||
|
|
||||||
|
val2, _ := <-ch
|
||||||
|
assert.Equal(2, val2)
|
||||||
|
|
||||||
|
val3, _ := <-ch
|
||||||
|
assert.Equal(3, val3)
|
||||||
|
|
||||||
|
_, ok := <-ch
|
||||||
|
assert.Equal(false, ok)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEncodeByte(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestEncodeByte")
|
||||||
|
|
||||||
|
byteData, _ := EncodeByte("abc")
|
||||||
|
expected := []byte{6, 12, 0, 3, 97, 98, 99}
|
||||||
|
|
||||||
|
assert.Equal(expected, byteData)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDecodeByte(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestDecodeByte")
|
||||||
|
|
||||||
|
var obj string
|
||||||
|
byteData := []byte{6, 12, 0, 3, 97, 98, 99}
|
||||||
|
DecodeByte(byteData, &obj)
|
||||||
|
assert.Equal("abc", obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeepClone(t *testing.T) {
|
||||||
|
// assert := internal.NewAssert(t, "TestDeepClone")
|
||||||
|
|
||||||
|
type Struct struct {
|
||||||
|
Str string
|
||||||
|
Int int
|
||||||
|
Float float64
|
||||||
|
Bool bool
|
||||||
|
Nil interface{}
|
||||||
|
unexported string
|
||||||
|
}
|
||||||
|
|
||||||
|
cases := []interface{}{
|
||||||
|
true,
|
||||||
|
1,
|
||||||
|
0.1,
|
||||||
|
map[string]int{
|
||||||
|
"a": 1,
|
||||||
|
"b": 2,
|
||||||
|
},
|
||||||
|
&Struct{
|
||||||
|
Str: "test",
|
||||||
|
Int: 1,
|
||||||
|
Float: 0.1,
|
||||||
|
Bool: true,
|
||||||
|
Nil: nil,
|
||||||
|
// unexported: "can't be cloned",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, item := range cases {
|
||||||
|
cloned := DeepClone(item)
|
||||||
|
|
||||||
|
t.Log(cloned)
|
||||||
|
if &cloned == &item {
|
||||||
|
t.Fatalf("[TestDeepClone case #%d failed]: equal pointer", i)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(item, cloned) {
|
||||||
|
t.Fatalf("[TestDeepClone case #%d failed] unequal objects", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCopyProperties(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestCopyProperties")
|
||||||
|
|
||||||
|
type Disk struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Total string `json:"total"`
|
||||||
|
Used string `json:"used"`
|
||||||
|
Percent float64 `json:"percent"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DiskVO struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Total string `json:"total"`
|
||||||
|
Used string `json:"used"`
|
||||||
|
Percent float64 `json:"percent"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Indicator struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
Ip string `json:"ip"`
|
||||||
|
UpTime string `json:"upTime"`
|
||||||
|
LoadAvg string `json:"loadAvg"`
|
||||||
|
Cpu int `json:"cpu"`
|
||||||
|
Disk []Disk `json:"disk"`
|
||||||
|
Stop chan bool `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type IndicatorVO struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
Ip string `json:"ip"`
|
||||||
|
UpTime string `json:"upTime"`
|
||||||
|
LoadAvg string `json:"loadAvg"`
|
||||||
|
Cpu int64 `json:"cpu"`
|
||||||
|
Disk []DiskVO `json:"disk"`
|
||||||
|
}
|
||||||
|
|
||||||
|
indicator := &Indicator{Id: "001", Ip: "127.0.0.1", Cpu: 1, Disk: []Disk{
|
||||||
|
{Name: "disk-001", Total: "100", Used: "1", Percent: 10},
|
||||||
|
{Name: "disk-002", Total: "200", Used: "1", Percent: 20},
|
||||||
|
{Name: "disk-003", Total: "300", Used: "1", Percent: 30},
|
||||||
|
}}
|
||||||
|
|
||||||
|
indicatorVO := IndicatorVO{}
|
||||||
|
|
||||||
|
err := CopyProperties(&indicatorVO, indicator)
|
||||||
|
|
||||||
|
assert.IsNil(err)
|
||||||
|
assert.Equal("001", indicatorVO.Id)
|
||||||
|
assert.Equal("127.0.0.1", indicatorVO.Ip)
|
||||||
|
assert.Equal(3, len(indicatorVO.Disk))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestToInterface(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestToInterface")
|
||||||
|
|
||||||
|
cases := []reflect.Value{
|
||||||
|
reflect.ValueOf("abc"),
|
||||||
|
reflect.ValueOf(int(0)), reflect.ValueOf(int8(1)), reflect.ValueOf(int16(-1)), reflect.ValueOf(int32(123)), reflect.ValueOf(int64(123)),
|
||||||
|
reflect.ValueOf(uint(123)), reflect.ValueOf(uint8(123)), reflect.ValueOf(uint16(123)), reflect.ValueOf(uint32(123)), reflect.ValueOf(uint64(123)),
|
||||||
|
reflect.ValueOf(float64(12.3)), reflect.ValueOf(float32(12.3)),
|
||||||
|
reflect.ValueOf(true), reflect.ValueOf(false),
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := []interface{}{
|
||||||
|
"abc",
|
||||||
|
0, int8(1), int16(-1), int32(123), int64(123),
|
||||||
|
uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
|
||||||
|
float64(12.3), float32(12.3),
|
||||||
|
true, false,
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(cases); i++ {
|
||||||
|
actual, _ := ToInterface(cases[i])
|
||||||
|
assert.Equal(expected[i], actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
nilVal, ok := ToInterface(reflect.ValueOf(nil))
|
||||||
|
assert.EqualValues(nil, nilVal)
|
||||||
|
assert.Equal(false, ok)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUtf8ToGbk(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestUtf8ToGbk")
|
||||||
|
|
||||||
|
utf8Data := []byte("hello")
|
||||||
|
gbkData, err := Utf8ToGbk(utf8Data)
|
||||||
|
|
||||||
|
assert.Equal(true, utf8.Valid(utf8Data))
|
||||||
|
assert.Equal(true, validator.IsGBK(gbkData))
|
||||||
|
assert.IsNil(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGbkToUtf8(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestGbkToUtf8")
|
||||||
|
|
||||||
|
gbkData, err := Utf8ToGbk([]byte("hello"))
|
||||||
|
utf8Data, err := GbkToUtf8(gbkData)
|
||||||
|
|
||||||
|
assert.IsNil(err)
|
||||||
|
assert.Equal(true, utf8.Valid(utf8Data))
|
||||||
|
assert.Equal("hello", string(utf8Data))
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,14 +17,23 @@ import (
|
|||||||
// AesEcbEncrypt encrypt data with key use AES ECB algorithm
|
// AesEcbEncrypt encrypt data with key use AES ECB algorithm
|
||||||
// len(key) should be 16, 24 or 32
|
// len(key) should be 16, 24 or 32
|
||||||
func AesEcbEncrypt(data, key []byte) []byte {
|
func AesEcbEncrypt(data, key []byte) []byte {
|
||||||
cipher, _ := aes.NewCipher(generateAesKey(key))
|
size := len(key)
|
||||||
|
if size != 16 && size != 24 && size != 32 {
|
||||||
|
panic("key length shoud be 16 or 24 or 32")
|
||||||
|
}
|
||||||
|
|
||||||
|
cipher, _ := aes.NewCipher(generateAesKey(key, size))
|
||||||
length := (len(data) + aes.BlockSize) / aes.BlockSize
|
length := (len(data) + aes.BlockSize) / aes.BlockSize
|
||||||
|
|
||||||
plain := make([]byte, length*aes.BlockSize)
|
plain := make([]byte, length*aes.BlockSize)
|
||||||
|
|
||||||
copy(plain, data)
|
copy(plain, data)
|
||||||
|
|
||||||
pad := byte(len(plain) - len(data))
|
pad := byte(len(plain) - len(data))
|
||||||
for i := len(data); i < len(plain); i++ {
|
for i := len(data); i < len(plain); i++ {
|
||||||
plain[i] = pad
|
plain[i] = pad
|
||||||
}
|
}
|
||||||
|
|
||||||
encrypted := make([]byte, len(plain))
|
encrypted := make([]byte, len(plain))
|
||||||
for bs, be := 0, cipher.BlockSize(); bs <= len(data); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
|
for bs, be := 0, cipher.BlockSize(); bs <= len(data); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
|
||||||
cipher.Encrypt(encrypted[bs:be], plain[bs:be])
|
cipher.Encrypt(encrypted[bs:be], plain[bs:be])
|
||||||
@@ -36,9 +45,14 @@ func AesEcbEncrypt(data, key []byte) []byte {
|
|||||||
// AesEcbDecrypt decrypt data with key use AES ECB algorithm
|
// AesEcbDecrypt decrypt data with key use AES ECB algorithm
|
||||||
// len(key) should be 16, 24 or 32
|
// len(key) should be 16, 24 or 32
|
||||||
func AesEcbDecrypt(encrypted, key []byte) []byte {
|
func AesEcbDecrypt(encrypted, key []byte) []byte {
|
||||||
cipher, _ := aes.NewCipher(generateAesKey(key))
|
size := len(key)
|
||||||
|
if size != 16 && size != 24 && size != 32 {
|
||||||
|
panic("key length shoud be 16 or 24 or 32")
|
||||||
|
}
|
||||||
|
|
||||||
|
cipher, _ := aes.NewCipher(generateAesKey(key, size))
|
||||||
decrypted := make([]byte, len(encrypted))
|
decrypted := make([]byte, len(encrypted))
|
||||||
//
|
|
||||||
for bs, be := 0, cipher.BlockSize(); bs < len(encrypted); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
|
for bs, be := 0, cipher.BlockSize(); bs < len(encrypted); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
|
||||||
cipher.Decrypt(decrypted[bs:be], encrypted[bs:be])
|
cipher.Decrypt(decrypted[bs:be], encrypted[bs:be])
|
||||||
}
|
}
|
||||||
@@ -54,14 +68,18 @@ func AesEcbDecrypt(encrypted, key []byte) []byte {
|
|||||||
// AesCbcEncrypt encrypt data with key use AES CBC algorithm
|
// AesCbcEncrypt encrypt data with key use AES CBC algorithm
|
||||||
// len(key) should be 16, 24 or 32
|
// len(key) should be 16, 24 or 32
|
||||||
func AesCbcEncrypt(data, key []byte) []byte {
|
func AesCbcEncrypt(data, key []byte) []byte {
|
||||||
// len(key) should be 16, 24 or 32
|
|
||||||
block, _ := aes.NewCipher(key)
|
block, _ := aes.NewCipher(key)
|
||||||
blockSize := block.BlockSize()
|
data = pkcs7Padding(data, block.BlockSize())
|
||||||
data = pkcs7Padding(data, blockSize)
|
|
||||||
blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
|
encrypted := make([]byte, aes.BlockSize+len(data))
|
||||||
|
iv := encrypted[:aes.BlockSize]
|
||||||
|
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
mode := cipher.NewCBCEncrypter(block, iv)
|
||||||
|
mode.CryptBlocks(encrypted[aes.BlockSize:], data)
|
||||||
|
|
||||||
encrypted := make([]byte, len(data))
|
|
||||||
blockMode.CryptBlocks(encrypted, data)
|
|
||||||
return encrypted
|
return encrypted
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,12 +87,14 @@ func AesCbcEncrypt(data, key []byte) []byte {
|
|||||||
// len(key) should be 16, 24 or 32
|
// len(key) should be 16, 24 or 32
|
||||||
func AesCbcDecrypt(encrypted, key []byte) []byte {
|
func AesCbcDecrypt(encrypted, key []byte) []byte {
|
||||||
block, _ := aes.NewCipher(key)
|
block, _ := aes.NewCipher(key)
|
||||||
blockSize := block.BlockSize()
|
|
||||||
blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
|
|
||||||
|
|
||||||
decrypted := make([]byte, len(encrypted))
|
iv := encrypted[:aes.BlockSize]
|
||||||
blockMode.CryptBlocks(decrypted, encrypted)
|
encrypted = encrypted[aes.BlockSize:]
|
||||||
decrypted = pkcs7UnPadding(decrypted)
|
|
||||||
|
mode := cipher.NewCBCDecrypter(block, iv)
|
||||||
|
mode.CryptBlocks(encrypted, encrypted)
|
||||||
|
|
||||||
|
decrypted := pkcs7UnPadding(encrypted)
|
||||||
return decrypted
|
return decrypted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package cryptor
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/duke-git/lancet/v2/internal"
|
"github.com/duke-git/lancet/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAesEcbEncrypt(t *testing.T) {
|
func TestAesEcbEncrypt(t *testing.T) {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package cryptor
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/duke-git/lancet/v2/internal"
|
"github.com/duke-git/lancet/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestBase64StdEncode(t *testing.T) {
|
func TestBase64StdEncode(t *testing.T) {
|
||||||
|
|||||||
@@ -2,15 +2,15 @@ package cryptor
|
|||||||
|
|
||||||
import "bytes"
|
import "bytes"
|
||||||
|
|
||||||
func generateAesKey(key []byte) []byte {
|
func generateAesKey(key []byte, size int) []byte {
|
||||||
genKey := make([]byte, 16)
|
aesKey := make([]byte, size)
|
||||||
copy(genKey, key)
|
copy(aesKey, key)
|
||||||
for i := 16; i < len(key); {
|
for i := size; i < len(key); {
|
||||||
for j := 0; j < 16 && i < len(key); j, i = j+1, i+1 {
|
for j := 0; j < size && i < len(key); j, i = j+1, i+1 {
|
||||||
genKey[j] ^= key[i]
|
aesKey[j] ^= key[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return genKey
|
return aesKey
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateDesKey(key []byte) []byte {
|
func generateDesKey(key []byte) []byte {
|
||||||
|
|||||||
@@ -55,12 +55,16 @@ func DesEcbDecrypt(encrypted, key []byte) []byte {
|
|||||||
// len(key) should be 8
|
// len(key) should be 8
|
||||||
func DesCbcEncrypt(data, key []byte) []byte {
|
func DesCbcEncrypt(data, key []byte) []byte {
|
||||||
block, _ := des.NewCipher(key)
|
block, _ := des.NewCipher(key)
|
||||||
blockSize := block.BlockSize()
|
data = pkcs7Padding(data, block.BlockSize())
|
||||||
data = pkcs7Padding(data, blockSize)
|
|
||||||
blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
|
|
||||||
|
|
||||||
encrypted := make([]byte, len(data))
|
encrypted := make([]byte, des.BlockSize+len(data))
|
||||||
blockMode.CryptBlocks(encrypted, data)
|
iv := encrypted[:des.BlockSize]
|
||||||
|
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
mode := cipher.NewCBCEncrypter(block, iv)
|
||||||
|
mode.CryptBlocks(encrypted[des.BlockSize:], data)
|
||||||
|
|
||||||
return encrypted
|
return encrypted
|
||||||
}
|
}
|
||||||
@@ -69,13 +73,14 @@ func DesCbcEncrypt(data, key []byte) []byte {
|
|||||||
// len(key) should be 8
|
// len(key) should be 8
|
||||||
func DesCbcDecrypt(encrypted, key []byte) []byte {
|
func DesCbcDecrypt(encrypted, key []byte) []byte {
|
||||||
block, _ := des.NewCipher(key)
|
block, _ := des.NewCipher(key)
|
||||||
blockSize := block.BlockSize()
|
|
||||||
blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
|
|
||||||
|
|
||||||
decrypted := make([]byte, len(encrypted))
|
iv := encrypted[:des.BlockSize]
|
||||||
blockMode.CryptBlocks(decrypted, encrypted)
|
encrypted = encrypted[des.BlockSize:]
|
||||||
decrypted = pkcs7UnPadding(decrypted)
|
|
||||||
|
|
||||||
|
mode := cipher.NewCBCDecrypter(block, iv)
|
||||||
|
mode.CryptBlocks(encrypted, encrypted)
|
||||||
|
|
||||||
|
decrypted := pkcs7UnPadding(encrypted)
|
||||||
return decrypted
|
return decrypted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package cryptor
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/duke-git/lancet/v2/internal"
|
"github.com/duke-git/lancet/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDesEcbEncrypt(t *testing.T) {
|
func TestDesEcbEncrypt(t *testing.T) {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package cryptor
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/duke-git/lancet/v2/internal"
|
"github.com/duke-git/lancet/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRsaEncrypt(t *testing.T) {
|
func TestRsaEncrypt(t *testing.T) {
|
||||||
|
|||||||
@@ -1,241 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
@@ -1,179 +0,0 @@
|
|||||||
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())
|
|
||||||
}
|
|
||||||
@@ -1,246 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
@@ -1,208 +0,0 @@
|
|||||||
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())
|
|
||||||
}
|
|
||||||
@@ -1,245 +0,0 @@
|
|||||||
// 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
|
|
||||||
}
|
|
||||||
@@ -1,272 +0,0 @@
|
|||||||
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))
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
// 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}
|
|
||||||
}
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
package datastructure
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ArrayQueue implements queue with slice
|
|
||||||
type ArrayQueue[T any] struct {
|
|
||||||
items []T
|
|
||||||
head int
|
|
||||||
tail int
|
|
||||||
capacity int
|
|
||||||
size int
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewArrayQueue[T any](capacity int) *ArrayQueue[T] {
|
|
||||||
return &ArrayQueue[T]{
|
|
||||||
items: make([]T, 0, capacity),
|
|
||||||
head: 0,
|
|
||||||
tail: 0,
|
|
||||||
capacity: capacity,
|
|
||||||
size: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Data return queue data
|
|
||||||
func (q *ArrayQueue[T]) Data() []T {
|
|
||||||
items := []T{}
|
|
||||||
for i := q.head; i < q.tail; i++ {
|
|
||||||
items = append(items, q.items[i])
|
|
||||||
}
|
|
||||||
return items
|
|
||||||
}
|
|
||||||
|
|
||||||
// Size return length of queue data
|
|
||||||
func (q *ArrayQueue[T]) Size() int {
|
|
||||||
return q.size
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsEmpty checks if queue is empty or not
|
|
||||||
func (q *ArrayQueue[T]) IsEmpty() bool {
|
|
||||||
return q.size == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Front return front value of queue
|
|
||||||
func (q *ArrayQueue[T]) Front() T {
|
|
||||||
return q.items[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Back return back value of queue
|
|
||||||
func (q *ArrayQueue[T]) Back() T {
|
|
||||||
return q.items[q.size-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
// EnQueue put element into queue
|
|
||||||
func (q *ArrayQueue[T]) Enqueue(item T) bool {
|
|
||||||
if q.head == 0 && q.tail == q.capacity {
|
|
||||||
return false
|
|
||||||
} else if q.head != 0 && q.tail == q.capacity {
|
|
||||||
for i := q.head; i < q.tail; i++ {
|
|
||||||
q.items[i-q.head] = q.items[i]
|
|
||||||
}
|
|
||||||
q.tail = q.tail - q.head
|
|
||||||
q.head = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
q.items = append(q.items, item)
|
|
||||||
q.tail++
|
|
||||||
q.size++
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeQueue remove head element of queue and return it, if queue is empty, return nil and error
|
|
||||||
func (q *ArrayQueue[T]) Dequeue() (T, bool) {
|
|
||||||
var item T
|
|
||||||
if q.head == q.tail {
|
|
||||||
return item, false
|
|
||||||
}
|
|
||||||
item = q.items[q.head]
|
|
||||||
q.head++
|
|
||||||
q.size--
|
|
||||||
return item, true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear the queue data
|
|
||||||
func (q *ArrayQueue[T]) Clear() {
|
|
||||||
capacity := q.capacity
|
|
||||||
q.items = make([]T, 0, capacity)
|
|
||||||
q.head = 0
|
|
||||||
q.tail = 0
|
|
||||||
q.size = 0
|
|
||||||
q.capacity = capacity
|
|
||||||
}
|
|
||||||
|
|
||||||
// Contain checks if the value is in queue or not
|
|
||||||
func (q *ArrayQueue[T]) Contain(value T) bool {
|
|
||||||
for _, v := range q.items {
|
|
||||||
if reflect.DeepEqual(v, value) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print queue data
|
|
||||||
func (q *ArrayQueue[T]) Print() {
|
|
||||||
info := "["
|
|
||||||
for i := q.head; i < q.tail; i++ {
|
|
||||||
info += fmt.Sprintf("%+v, ", q.items[i])
|
|
||||||
}
|
|
||||||
info += "]"
|
|
||||||
fmt.Println(info)
|
|
||||||
}
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
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](5)
|
|
||||||
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[int](4)
|
|
||||||
queue.Enqueue(1)
|
|
||||||
queue.Enqueue(2)
|
|
||||||
queue.Enqueue(3)
|
|
||||||
|
|
||||||
val, ok := queue.Dequeue()
|
|
||||||
assert.Equal(true, ok)
|
|
||||||
|
|
||||||
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[int](4)
|
|
||||||
queue.Enqueue(1)
|
|
||||||
queue.Enqueue(2)
|
|
||||||
queue.Enqueue(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[int](4)
|
|
||||||
queue.Enqueue(1)
|
|
||||||
queue.Enqueue(2)
|
|
||||||
queue.Enqueue(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[int](4)
|
|
||||||
queue.Enqueue(1)
|
|
||||||
queue.Enqueue(2)
|
|
||||||
queue.Enqueue(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](4)
|
|
||||||
|
|
||||||
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())
|
|
||||||
}
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
@@ -1,148 +0,0 @@
|
|||||||
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())
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
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())
|
|
||||||
}
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// SymmetricDifference creates a new set whose element is in set1 or set2, but not in both sets
|
|
||||||
func (s Set[T]) SymmetricDifference(other Set[T]) Set[T] {
|
|
||||||
set := NewSet[T]()
|
|
||||||
s.Iterate(func(value T) {
|
|
||||||
if !other.Contain(value) {
|
|
||||||
set.Add(value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
other.Iterate(func(value T) {
|
|
||||||
if !s.Contain(value) {
|
|
||||||
set.Add(value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return set
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minus creates an set of whose element in origin set but not in compared set
|
|
||||||
func (s Set[T]) Minus(comparedSet Set[T]) Set[T] {
|
|
||||||
set := NewSet[T]()
|
|
||||||
|
|
||||||
s.Iterate(func(value T) {
|
|
||||||
if !comparedSet.Contain(value) {
|
|
||||||
set.Add(value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return set
|
|
||||||
}
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSet_SymmetricDifference(t *testing.T) {
|
|
||||||
assert := internal.NewAssert(t, "TestSet_SymmetricDifference")
|
|
||||||
|
|
||||||
set1 := NewSet(1, 2, 3)
|
|
||||||
set2 := NewSet(2, 3, 4, 5)
|
|
||||||
|
|
||||||
assert.Equal(NewSet(1, 4, 5), set1.SymmetricDifference(set2))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSet_Minus(t *testing.T) {
|
|
||||||
assert := internal.NewAssert(t, "TestSet_Minus")
|
|
||||||
|
|
||||||
set1 := NewSet(1, 2, 3)
|
|
||||||
set2 := NewSet(2, 3, 4, 5)
|
|
||||||
set3 := NewSet(2, 3)
|
|
||||||
|
|
||||||
assert.Equal(NewSet(1), set1.Minus(set2))
|
|
||||||
assert.Equal(NewSet(4, 5), set2.Minus(set3))
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
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())
|
|
||||||
}
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
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())
|
|
||||||
}
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
@@ -1,224 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,7 @@ package datetime
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/duke-git/lancet/v2/internal"
|
"github.com/duke-git/lancet/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestToUnix(t *testing.T) {
|
func TestToUnix(t *testing.T) {
|
||||||
@@ -19,10 +19,10 @@ func TestToUnix(t *testing.T) {
|
|||||||
func TestToFormat(t *testing.T) {
|
func TestToFormat(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestToFormat")
|
assert := internal.NewAssert(t, "TestToFormat")
|
||||||
|
|
||||||
_, err := NewFormat("2022/03/18 17:04:05")
|
tm, err := NewFormat("2022/03/18 17:04:05")
|
||||||
assert.IsNotNil(err)
|
assert.IsNotNil(err)
|
||||||
|
|
||||||
tm, err := NewFormat("2022-03-18 17:04:05")
|
tm, err = NewFormat("2022-03-18 17:04:05")
|
||||||
assert.IsNil(err)
|
assert.IsNil(err)
|
||||||
|
|
||||||
t.Log("ToFormat -> ", tm.ToFormat())
|
t.Log("ToFormat -> ", tm.ToFormat())
|
||||||
@@ -31,22 +31,23 @@ func TestToFormat(t *testing.T) {
|
|||||||
func TestToFormatForTpl(t *testing.T) {
|
func TestToFormatForTpl(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestToFormatForTpl")
|
assert := internal.NewAssert(t, "TestToFormatForTpl")
|
||||||
|
|
||||||
_, err := NewFormat("2022/03/18 17:04:05")
|
tm, err := NewFormat("2022/03/18 17:04:05")
|
||||||
assert.IsNotNil(err)
|
assert.IsNotNil(err)
|
||||||
|
|
||||||
tm, err := NewFormat("2022-03-18 17:04:05")
|
tm, err = NewFormat("2022-03-18 17:04:05")
|
||||||
assert.IsNil(err)
|
assert.IsNil(err)
|
||||||
|
|
||||||
t.Log("ToFormatForTpl -> ", tm.ToFormatForTpl("2006/01/02 15:04:05"))
|
t.Log("ToFormatForTpl -> ", tm.ToFormatForTpl("2006/01/02 15:04:05"))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToIso8601(t *testing.T) {
|
func TestToIso8601(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestToIso8601")
|
assert := internal.NewAssert(t, "TestToIso8601")
|
||||||
|
|
||||||
_, err := NewISO8601("2022-03-18 17:04:05")
|
tm, err := NewISO8601("2022-03-18 17:04:05")
|
||||||
assert.IsNotNil(err)
|
assert.IsNotNil(err)
|
||||||
|
|
||||||
tm, err := NewISO8601("2006-01-02T15:04:05.999Z")
|
tm, err = NewISO8601("2006-01-02T15:04:05.999Z")
|
||||||
assert.IsNil(err)
|
assert.IsNil(err)
|
||||||
|
|
||||||
t.Log("ToIso8601 -> ", tm.ToIso8601())
|
t.Log("ToIso8601 -> ", tm.ToIso8601())
|
||||||
|
|||||||
@@ -4,24 +4,24 @@
|
|||||||
// Package datetime implements some functions to format date and time.
|
// Package datetime implements some functions to format date and time.
|
||||||
// Note:
|
// Note:
|
||||||
// 1. `format` param in FormatTimeToStr function should be as flow:
|
// 1. `format` param in FormatTimeToStr function should be as flow:
|
||||||
//"yyyy-mm-dd hh:mm:ss"
|
// "yyyy-mm-dd hh:mm:ss"
|
||||||
//"yyyy-mm-dd hh:mm"
|
// "yyyy-mm-dd hh:mm"
|
||||||
//"yyyy-mm-dd hh"
|
// "yyyy-mm-dd hh"
|
||||||
//"yyyy-mm-dd"
|
// "yyyy-mm-dd"
|
||||||
//"yyyy-mm"
|
// "yyyy-mm"
|
||||||
//"mm-dd"
|
// "mm-dd"
|
||||||
//"dd-mm-yy hh:mm:ss"
|
// "dd-mm-yy hh:mm:ss"
|
||||||
//"yyyy/mm/dd hh:mm:ss"
|
// "yyyy/mm/dd hh:mm:ss"
|
||||||
//"yyyy/mm/dd hh:mm"
|
// "yyyy/mm/dd hh:mm"
|
||||||
//"yyyy/mm/dd hh"
|
// "yyyy/mm/dd hh"
|
||||||
//"yyyy/mm/dd"
|
// "yyyy/mm/dd"
|
||||||
//"yyyy/mm"
|
// "yyyy/mm"
|
||||||
//"mm/dd"
|
// "mm/dd"
|
||||||
//"dd/mm/yy hh:mm:ss"
|
// "dd/mm/yy hh:mm:ss"
|
||||||
//"yyyy"
|
// "yyyy"
|
||||||
//"mm"
|
// "mm"
|
||||||
//"hh:mm:ss"
|
// "hh:mm:ss"
|
||||||
//"mm:ss"
|
// "mm:ss"
|
||||||
package datetime
|
package datetime
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -35,7 +35,7 @@ func init() {
|
|||||||
timeFormat = map[string]string{
|
timeFormat = map[string]string{
|
||||||
"yyyy-mm-dd hh:mm:ss": "2006-01-02 15:04:05",
|
"yyyy-mm-dd hh:mm:ss": "2006-01-02 15:04:05",
|
||||||
"yyyy-mm-dd hh:mm": "2006-01-02 15:04",
|
"yyyy-mm-dd hh:mm": "2006-01-02 15:04",
|
||||||
"yyyy-mm-dd hh": "2006-01-02 15:04",
|
"yyyy-mm-dd hh": "2006-01-02 15",
|
||||||
"yyyy-mm-dd": "2006-01-02",
|
"yyyy-mm-dd": "2006-01-02",
|
||||||
"yyyy-mm": "2006-01",
|
"yyyy-mm": "2006-01",
|
||||||
"mm-dd": "01-02",
|
"mm-dd": "01-02",
|
||||||
@@ -69,6 +69,11 @@ func AddDay(t time.Time, day int64) time.Time {
|
|||||||
return t.Add(24 * time.Hour * time.Duration(day))
|
return t.Add(24 * time.Hour * time.Duration(day))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddYear add or sub year to the time.
|
||||||
|
func AddYear(t time.Time, year int64) time.Time {
|
||||||
|
return t.Add(365 * 24 * time.Hour * time.Duration(year))
|
||||||
|
}
|
||||||
|
|
||||||
// GetNowDate return format yyyy-mm-dd of current date
|
// GetNowDate return format yyyy-mm-dd of current date
|
||||||
func GetNowDate() string {
|
func GetNowDate() string {
|
||||||
return time.Now().Format("2006-01-02")
|
return time.Now().Format("2006-01-02")
|
||||||
@@ -180,3 +185,28 @@ func BeginOfYear(t time.Time) time.Time {
|
|||||||
func EndOfYear(t time.Time) time.Time {
|
func EndOfYear(t time.Time) time.Time {
|
||||||
return BeginOfYear(t).AddDate(1, 0, 0).Add(-time.Nanosecond)
|
return BeginOfYear(t).AddDate(1, 0, 0).Add(-time.Nanosecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsLeapYear check if param year is leap year or not.
|
||||||
|
func IsLeapYear(year int) bool {
|
||||||
|
return year%4 == 0 && (year%100 != 0 || year%400 == 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BetweenSeconds returns the number of seconds between two times.
|
||||||
|
func BetweenSeconds(t1 time.Time, t2 time.Time) int64 {
|
||||||
|
index := t2.Unix() - t1.Unix()
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
|
||||||
|
// DayOfYear returns which day of the year the parameter date `t` is.
|
||||||
|
func DayOfYear(t time.Time) int {
|
||||||
|
y, m, d := t.Date()
|
||||||
|
firstDay := time.Date(y, 1, 1, 0, 0, 0, 0, t.Location())
|
||||||
|
nowDate := time.Date(y, m, d, 0, 0, 0, 0, t.Location())
|
||||||
|
|
||||||
|
return int(nowDate.Sub(firstDay).Hours() / 24)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsWeekend checks if passed time is weekend or not.
|
||||||
|
func IsWeekend(t time.Time) bool {
|
||||||
|
return time.Saturday == t.Weekday() || time.Sunday == t.Weekday()
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/duke-git/lancet/v2/internal"
|
"github.com/duke-git/lancet/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAddDay(t *testing.T) {
|
func TestAddDay(t *testing.T) {
|
||||||
@@ -46,6 +46,19 @@ func TestAddMinute(t *testing.T) {
|
|||||||
assert.Equal(float64(-2), diff2.Minutes())
|
assert.Equal(float64(-2), diff2.Minutes())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAddYear(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestAddDay")
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
after2Years := AddYear(now, 1)
|
||||||
|
diff1 := after2Years.Sub(now)
|
||||||
|
assert.Equal(float64(8760), diff1.Hours())
|
||||||
|
|
||||||
|
before2Years := AddYear(now, -1)
|
||||||
|
diff2 := before2Years.Sub(now)
|
||||||
|
assert.Equal(float64(-8760), diff2.Hours())
|
||||||
|
}
|
||||||
|
|
||||||
func TestGetNowDate(t *testing.T) {
|
func TestGetNowDate(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestGetNowDate")
|
assert := internal.NewAssert(t, "TestGetNowDate")
|
||||||
expected := time.Now().Format("2006-01-02")
|
expected := time.Now().Format("2006-01-02")
|
||||||
@@ -231,3 +244,57 @@ func TestEndOfYear(t *testing.T) {
|
|||||||
|
|
||||||
assert.Equal(expected, actual)
|
assert.Equal(expected, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIsLeapYear(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestEndOfYear")
|
||||||
|
|
||||||
|
result1 := IsLeapYear(2000)
|
||||||
|
result2 := IsLeapYear(2001)
|
||||||
|
|
||||||
|
assert.Equal(true, result1)
|
||||||
|
assert.Equal(false, result2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBetweenSeconds(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestBetweenSeconds")
|
||||||
|
|
||||||
|
today := time.Now()
|
||||||
|
tomorrow := AddDay(today, 1)
|
||||||
|
yesterday := AddDay(today, -1)
|
||||||
|
|
||||||
|
result1 := BetweenSeconds(today, tomorrow)
|
||||||
|
result2 := BetweenSeconds(today, yesterday)
|
||||||
|
|
||||||
|
assert.Equal(int64(86400), result1)
|
||||||
|
assert.Equal(int64(-86400), result2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDayOfYear(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestDayOfYear")
|
||||||
|
date1 := time.Date(2023, 02, 01, 1, 1, 1, 0, time.Local)
|
||||||
|
result1 := DayOfYear(date1)
|
||||||
|
assert.Equal(31, result1)
|
||||||
|
|
||||||
|
date2 := time.Date(2023, 01, 02, 1, 1, 1, 0, time.Local)
|
||||||
|
result2 := DayOfYear(date2)
|
||||||
|
assert.Equal(1, result2)
|
||||||
|
|
||||||
|
date3 := time.Date(2023, 01, 01, 1, 1, 1, 0, time.Local)
|
||||||
|
result3 := DayOfYear(date3)
|
||||||
|
assert.Equal(0, result3)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsWeekend(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestIsWeekend")
|
||||||
|
date := time.Date(2023, 06, 03, 0, 0, 0, 0, time.Local)
|
||||||
|
result := IsWeekend(date)
|
||||||
|
assert.Equal(true, result)
|
||||||
|
|
||||||
|
date1 := time.Date(2023, 06, 04, 0, 0, 0, 0, time.Local)
|
||||||
|
result1 := IsWeekend(date1)
|
||||||
|
assert.Equal(true, result1)
|
||||||
|
|
||||||
|
date2 := time.Date(2023, 06, 02, 0, 0, 0, 0, time.Local)
|
||||||
|
result2 := IsWeekend(date2)
|
||||||
|
assert.Equal(false, result2)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,598 +0,0 @@
|
|||||||
# 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
|
|
||||||
- [Algorithm](#algorithm)
|
|
||||||
- [Source](#source)
|
|
||||||
- [Usage](#usage)
|
|
||||||
- [Index](#index)
|
|
||||||
- [Documentation](#documentation)
|
|
||||||
- [<span id="BubbleSort">BubbleSort</span>](#bubblesort)
|
|
||||||
- [<span id="InsertionSort">InsertionSort</span>](#insertionsort)
|
|
||||||
- [<span id="SelectionSort">SelectionSort</span>](#selectionsort)
|
|
||||||
- [<span id="ShellSort">ShellSort</span>](#shellsort)
|
|
||||||
- [<span id="QuickSort">QuickSort</span>](#quicksort)
|
|
||||||
- [<span id="HeapSort">HeapSort</span>](#heapsort)
|
|
||||||
- [<span id="MergeSort">MergeSort</span>](#mergesort)
|
|
||||||
- [<span id="CountSort">CountSort</span>](#countsort)
|
|
||||||
- [<span id="BinarySearch">BinarySearch</span>](#binarysearch)
|
|
||||||
- [<span id="BinaryIterativeSearch">BinaryIterativeSearch</span>](#binaryiterativesearch)
|
|
||||||
- [<span id="LinearSearch">LinearSearch</span>](#linearsearch)
|
|
||||||
- [<span id="LRUCache">LRUCache</span>](#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)
|
|
||||||
```
|
|
||||||
<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{}
|
|
||||||
algorithm.BubbleSort(intSlice, comparator)
|
|
||||||
|
|
||||||
fmt.Println(intSlice) //[]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)
|
|
||||||
```
|
|
||||||
<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{}
|
|
||||||
algorithm.InsertionSort(peoples, comparator)
|
|
||||||
|
|
||||||
fmt.Println(peoples) //[{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)
|
|
||||||
```
|
|
||||||
<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{}
|
|
||||||
algorithm.SelectionSort(intSlice, comparator)
|
|
||||||
|
|
||||||
fmt.Println(intSlice) //[]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)
|
|
||||||
```
|
|
||||||
<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{}
|
|
||||||
algorithm.ShellSort(intSlice, comparator)
|
|
||||||
|
|
||||||
fmt.Println(intSlice) //[]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)
|
|
||||||
```
|
|
||||||
<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{}
|
|
||||||
algorithm.QuickSort(intSlice, 0, len(intSlice)-1, comparator)
|
|
||||||
|
|
||||||
fmt.Println(intSlice) //[]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)
|
|
||||||
```
|
|
||||||
<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{}
|
|
||||||
algorithm.HeapSort(intSlice, comparator)
|
|
||||||
|
|
||||||
fmt.Println(intSlice) //[]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, comparator lancetconstraints.Comparator)
|
|
||||||
```
|
|
||||||
<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{}
|
|
||||||
algorithm.MergeSort(intSlice, comparator)
|
|
||||||
|
|
||||||
fmt.Println(intSlice) //[]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
|
|
||||||
|
|
||||||
}
|
|
||||||
```
|
|
||||||
@@ -1,598 +0,0 @@
|
|||||||
# 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>
|
|
||||||
|
|
||||||
## 目录
|
|
||||||
- [Algorithm](#algorithm)
|
|
||||||
- [源码](#源码)
|
|
||||||
- [用法](#用法)
|
|
||||||
- [目录](#目录)
|
|
||||||
- [文档](#文档)
|
|
||||||
- [<span id="BubbleSort">BubbleSort</span>](#bubblesort)
|
|
||||||
- [<span id="InsertionSort">InsertionSort</span>](#insertionsort)
|
|
||||||
- [<span id="SelectionSort">SelectionSort</span>](#selectionsort)
|
|
||||||
- [<span id="ShellSort">ShellSort</span>](#shellsort)
|
|
||||||
- [<span id="QuickSort">QuickSort</span>](#quicksort)
|
|
||||||
- [<span id="HeapSort">HeapSort</span>](#heapsort)
|
|
||||||
- [<span id="MergeSort">MergeSort</span>](#mergesort)
|
|
||||||
- [<span id="CountSort">CountSort</span>](#countsort)
|
|
||||||
- [<span id="BinarySearch">BinarySearch</span>](#binarysearch)
|
|
||||||
- [<span id="BinaryIterativeSearch">BinaryIterativeSearch</span>](#binaryiterativesearch)
|
|
||||||
- [<span id="LinearSearch">LinearSearch</span>](#linearsearch)
|
|
||||||
- [<span id="LRUCache">LRUCache</span>](#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)
|
|
||||||
```
|
|
||||||
<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{}
|
|
||||||
algorithm.BubbleSort(intSlice, comparator)
|
|
||||||
|
|
||||||
fmt.Println(intSlice) //[]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)
|
|
||||||
```
|
|
||||||
<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{}
|
|
||||||
algorithm.InsertionSort(peoples, comparator)
|
|
||||||
|
|
||||||
fmt.Println(intSlice) //[{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)
|
|
||||||
```
|
|
||||||
<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{}
|
|
||||||
algorithm.SelectionSort(intSlice, comparator)
|
|
||||||
|
|
||||||
fmt.Println(intSlice) //[]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)
|
|
||||||
```
|
|
||||||
<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{}
|
|
||||||
algorithm.ShellSort(intSlice, comparator)
|
|
||||||
|
|
||||||
fmt.Println(intSlice) //[]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{}
|
|
||||||
algorithm.QuickSort(intSlice, 0, len(intSlice)-1, comparator)
|
|
||||||
|
|
||||||
fmt.Println(intSlice) //[]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{}
|
|
||||||
algorithm.HeapSort(intSlice, comparator)
|
|
||||||
|
|
||||||
fmt.Println(intSlice) //[]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, comparator lancetconstraints.Comparator)
|
|
||||||
```
|
|
||||||
<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{}
|
|
||||||
algorithm.MergeSort(intSlice, comparator)
|
|
||||||
|
|
||||||
fmt.Println(intSlice) //[]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
|
|
||||||
|
|
||||||
}
|
|
||||||
```
|
|
||||||
326
docs/compare.md
Normal file
326
docs/compare.md
Normal file
@@ -0,0 +1,326 @@
|
|||||||
|
# Compare
|
||||||
|
|
||||||
|
Package compare provides a lightweight comparison function on any type.
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## Source:
|
||||||
|
|
||||||
|
- [https://github.com/duke-git/lancet/blob/v1/compare/compare.go](https://github.com/duke-git/lancet/blob/v1/compare/compare.go)
|
||||||
|
|
||||||
|
- [https://github.com/duke-git/lancet/blob/v1/compare/compare_internal.go](https://github.com/duke-git/lancet/blob/v1/compare/compare_internal.go)
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## Usage:
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"github.com/duke-git/lancet/condition"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## Index
|
||||||
|
|
||||||
|
- [Equal](#Equal)
|
||||||
|
- [EqualValue](#EqualValue)
|
||||||
|
- [LessThan](#LessThan)
|
||||||
|
- [GreaterThan](#GreaterThan)
|
||||||
|
- [LessOrEqual](#LessOrEqual)
|
||||||
|
- [GreaterOrEqual](#GreaterOrEqual)
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
### <span id="Equal">Equal</span>
|
||||||
|
|
||||||
|
<p>Checks if two values are equal or not. (check both type and value)</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Equal(left, right any) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/compare"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := compare.Equal(1, 1)
|
||||||
|
result2 := compare.Equal("1", "1")
|
||||||
|
result3 := compare.Equal([]int{1, 2, 3}, []int{1, 2, 3})
|
||||||
|
result4 := compare.Equal(map[int]string{1: "a", 2: "b"}, map[int]string{1: "a", 2: "b"})
|
||||||
|
|
||||||
|
result5 := compare.Equal(1, "1")
|
||||||
|
result6 := compare.Equal(1, int64(1))
|
||||||
|
result7 := compare.Equal([]int{1, 2}, []int{1, 2, 3})
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
fmt.Println(result5)
|
||||||
|
fmt.Println(result6)
|
||||||
|
fmt.Println(result7)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="EqualValue">EqualValue</span>
|
||||||
|
|
||||||
|
<p>Checks if two values are equal or not. (check value only)</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func EqualValue(left, right any) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/compare"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := compare.EqualValue(1, 1)
|
||||||
|
result2 := compare.EqualValue(int(1), int64(1))
|
||||||
|
result3 := compare.EqualValue(1, "1")
|
||||||
|
result4 := compare.EqualValue(1, "2")
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="LessThan">LessThan</span>
|
||||||
|
|
||||||
|
<p>Checks if value `left` less than value `right`.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func LessThan(left, right any) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/compare"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := compare.LessThan(1, 2)
|
||||||
|
result2 := compare.LessThan(1.1, 2.2)
|
||||||
|
result3 := compare.LessThan("a", "b")
|
||||||
|
|
||||||
|
time1 := time.Now()
|
||||||
|
time2 := time1.Add(time.Second)
|
||||||
|
result4 := compare.LessThan(time1, time2)
|
||||||
|
|
||||||
|
result5 := compare.LessThan(2, 1)
|
||||||
|
result6 := compare.LessThan(1, int64(2))
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
fmt.Println(result5)
|
||||||
|
fmt.Println(result6)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="GreaterThan">GreaterThan</span>
|
||||||
|
|
||||||
|
<p>Checks if value `left` greater than value `right`.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GreaterThan(left, right any) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/compare"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := compare.GreaterThan(2, 1)
|
||||||
|
result2 := compare.GreaterThan(2.2, 1.1)
|
||||||
|
result3 := compare.GreaterThan("b", "a")
|
||||||
|
|
||||||
|
time1 := time.Now()
|
||||||
|
time2 := time1.Add(time.Second)
|
||||||
|
result4 := compare.GreaterThan(time2, time1)
|
||||||
|
|
||||||
|
result5 := compare.GreaterThan(1, 2)
|
||||||
|
result6 := compare.GreaterThan(int64(2), 1)
|
||||||
|
result7 := compare.GreaterThan("b", "c")
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
fmt.Println(result5)
|
||||||
|
fmt.Println(result6)
|
||||||
|
fmt.Println(result7)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="LessOrEqual">LessOrEqual</span>
|
||||||
|
|
||||||
|
<p>Checks if value `left` less than or equal than value `right`.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func LessOrEqual(left, right any) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/compare"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := compare.LessOrEqual(1, 1)
|
||||||
|
result2 := compare.LessOrEqual(1.1, 2.2)
|
||||||
|
result3 := compare.LessOrEqual("a", "b")
|
||||||
|
|
||||||
|
time1 := time.Now()
|
||||||
|
time2 := time1.Add(time.Second)
|
||||||
|
result4 := compare.LessOrEqual(time1, time2)
|
||||||
|
|
||||||
|
result5 := compare.LessOrEqual(2, 1)
|
||||||
|
result6 := compare.LessOrEqual(1, int64(2))
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
fmt.Println(result5)
|
||||||
|
fmt.Println(result6)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="GreaterOrEqual">GreaterOrEqual</span>
|
||||||
|
|
||||||
|
<p>Checks if value `left` less greater or equal than value `right`.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GreaterOrEqual(left, right any) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/compare"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := compare.GreaterOrEqual(1, 1)
|
||||||
|
result2 := compare.GreaterOrEqual(2.2, 1.1)
|
||||||
|
result3 := compare.GreaterOrEqual("b", "b")
|
||||||
|
|
||||||
|
time1 := time.Now()
|
||||||
|
time2 := time1.Add(time.Second)
|
||||||
|
result4 := compare.GreaterOrEqual(time2, time1)
|
||||||
|
|
||||||
|
result5 := compare.GreaterOrEqual(1, 2)
|
||||||
|
result6 := compare.GreaterOrEqual(int64(2), 1)
|
||||||
|
result7 := compare.GreaterOrEqual("b", "c")
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
fmt.Println(result5)
|
||||||
|
fmt.Println(result6)
|
||||||
|
fmt.Println(result7)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
326
docs/compare_zh-CN.md
Normal file
326
docs/compare_zh-CN.md
Normal file
@@ -0,0 +1,326 @@
|
|||||||
|
# Compare
|
||||||
|
|
||||||
|
compare包提供几个轻量级的类型比较函数。
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## 源码:
|
||||||
|
|
||||||
|
- [https://github.com/duke-git/lancet/blob/v1/compare/compare.go](https://github.com/duke-git/lancet/blob/v1/compare/compare.go)
|
||||||
|
|
||||||
|
- [https://github.com/duke-git/lancet/blob/v1/compare/compare_internal.go](https://github.com/duke-git/lancet/blob/v1/compare/compare_internal.go)
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## 用法:
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"github.com/duke-git/lancet/condition"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## 目录
|
||||||
|
|
||||||
|
- [Equal](#Equal)
|
||||||
|
- [EqualValue](#EqualValue)
|
||||||
|
- [LessThan](#LessThan)
|
||||||
|
- [GreaterThan](#GreaterThan)
|
||||||
|
- [LessOrEqual](#LessOrEqual)
|
||||||
|
- [GreaterOrEqual](#GreaterOrEqual)
|
||||||
|
|
||||||
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
### <span id="Equal">Equal</span>
|
||||||
|
|
||||||
|
<p>检查两个值是否相等(检查类型和值)</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Equal(left, right any) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/compare"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := compare.Equal(1, 1)
|
||||||
|
result2 := compare.Equal("1", "1")
|
||||||
|
result3 := compare.Equal([]int{1, 2, 3}, []int{1, 2, 3})
|
||||||
|
result4 := compare.Equal(map[int]string{1: "a", 2: "b"}, map[int]string{1: "a", 2: "b"})
|
||||||
|
|
||||||
|
result5 := compare.Equal(1, "1")
|
||||||
|
result6 := compare.Equal(1, int64(1))
|
||||||
|
result7 := compare.Equal([]int{1, 2}, []int{1, 2, 3})
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
fmt.Println(result5)
|
||||||
|
fmt.Println(result6)
|
||||||
|
fmt.Println(result7)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="EqualValue">EqualValue</span>
|
||||||
|
|
||||||
|
<p>检查两个值是否相等(只检查值)</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func EqualValue(left, right any) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/compare"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := compare.EqualValue(1, 1)
|
||||||
|
result2 := compare.EqualValue(int(1), int64(1))
|
||||||
|
result3 := compare.EqualValue(1, "1")
|
||||||
|
result4 := compare.EqualValue(1, "2")
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="LessThan">LessThan</span>
|
||||||
|
|
||||||
|
<p>验证参数`left`的值是否小于参数`right`的值。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func LessThan(left, right any) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/compare"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := compare.LessThan(1, 2)
|
||||||
|
result2 := compare.LessThan(1.1, 2.2)
|
||||||
|
result3 := compare.LessThan("a", "b")
|
||||||
|
|
||||||
|
time1 := time.Now()
|
||||||
|
time2 := time1.Add(time.Second)
|
||||||
|
result4 := compare.LessThan(time1, time2)
|
||||||
|
|
||||||
|
result5 := compare.LessThan(2, 1)
|
||||||
|
result6 := compare.LessThan(1, int64(2))
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
fmt.Println(result5)
|
||||||
|
fmt.Println(result6)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="GreaterThan">GreaterThan</span>
|
||||||
|
|
||||||
|
<p>验证参数`left`的值是否大于参数`right`的值。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GreaterThan(left, right any) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/compare"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := compare.GreaterThan(2, 1)
|
||||||
|
result2 := compare.GreaterThan(2.2, 1.1)
|
||||||
|
result3 := compare.GreaterThan("b", "a")
|
||||||
|
|
||||||
|
time1 := time.Now()
|
||||||
|
time2 := time1.Add(time.Second)
|
||||||
|
result4 := compare.GreaterThan(time2, time1)
|
||||||
|
|
||||||
|
result5 := compare.GreaterThan(1, 2)
|
||||||
|
result6 := compare.GreaterThan(int64(2), 1)
|
||||||
|
result7 := compare.GreaterThan("b", "c")
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
fmt.Println(result5)
|
||||||
|
fmt.Println(result6)
|
||||||
|
fmt.Println(result7)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="LessOrEqual">LessOrEqual</span>
|
||||||
|
|
||||||
|
<p>验证参数`left`的值是否小于或等于参数`right`的值。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func LessOrEqual(left, right any) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/compare"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := compare.LessOrEqual(1, 1)
|
||||||
|
result2 := compare.LessOrEqual(1.1, 2.2)
|
||||||
|
result3 := compare.LessOrEqual("a", "b")
|
||||||
|
|
||||||
|
time1 := time.Now()
|
||||||
|
time2 := time1.Add(time.Second)
|
||||||
|
result4 := compare.LessOrEqual(time1, time2)
|
||||||
|
|
||||||
|
result5 := compare.LessOrEqual(2, 1)
|
||||||
|
result6 := compare.LessOrEqual(1, int64(2))
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
fmt.Println(result5)
|
||||||
|
fmt.Println(result6)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="GreaterOrEqual">GreaterOrEqual</span>
|
||||||
|
|
||||||
|
<p>验证参数`left`的值是否大于或参数`right`的值。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GreaterOrEqual(left, right any) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/compare"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := compare.GreaterOrEqual(1, 1)
|
||||||
|
result2 := compare.GreaterOrEqual(2.2, 1.1)
|
||||||
|
result3 := compare.GreaterOrEqual("b", "b")
|
||||||
|
|
||||||
|
time1 := time.Now()
|
||||||
|
time2 := time1.Add(time.Second)
|
||||||
|
result4 := compare.GreaterOrEqual(time2, time1)
|
||||||
|
|
||||||
|
result5 := compare.GreaterOrEqual(1, 2)
|
||||||
|
result6 := compare.GreaterOrEqual(int64(2), 1)
|
||||||
|
result7 := compare.GreaterOrEqual("b", "c")
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
fmt.Println(result5)
|
||||||
|
fmt.Println(result6)
|
||||||
|
fmt.Println(result7)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -1,41 +1,53 @@
|
|||||||
# Convertor
|
# Convertor
|
||||||
|
|
||||||
Package convertor contains some functions for data type convertion.
|
Package convertor contains some functions for data type convertion.
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Source:
|
## Source:
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/convertor/convertor.go](https://github.com/duke-git/lancet/blob/main/convertor/convertor.go)
|
[https://github.com/duke-git/lancet/blob/v1/convertor/convertor.go](https://github.com/duke-git/lancet/blob/v1/convertor/convertor.go)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Usage:
|
## Usage:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/convertor"
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Index
|
## Index
|
||||||
- [ColorHexToRGB](#ColorHexToRGB)
|
|
||||||
- [ColorRGBToHex](#ColorRGBToHex)
|
- [ColorHexToRGB](#ColorHexToRGB)
|
||||||
- [ToBool](#ToBool)
|
- [ColorRGBToHex](#ColorRGBToHex)
|
||||||
- [ToBytes](#ToBytes)
|
- [ToBool](#ToBool)
|
||||||
- [ToChar](#ToChar)
|
- [ToBytes](#ToBytes)
|
||||||
- [ToInt](#ToInt)
|
- [ToChar](#ToChar)
|
||||||
- [ToJson](#ToJson)
|
- [ToChannel](#ToChannel)
|
||||||
- [ToString](#ToString)
|
- [ToFloat](#ToFloat)
|
||||||
- [StructToMap](#StructToMap)
|
- [ToInt](#ToInt)
|
||||||
|
- [ToJson](#ToJson)
|
||||||
|
- [ToString](#ToString)
|
||||||
|
- [StructToMap](#StructToMap)
|
||||||
|
- [EncodeByte](#EncodeByte)
|
||||||
|
- [DecodeByte](#DecodeByte)
|
||||||
|
- [DeepClone](#DeepClone)
|
||||||
|
- [CopyProperties](#CopyProperties)
|
||||||
|
- [ToInterface](#ToInterface)
|
||||||
|
- [Utf8ToGbk](#Utf8ToGbk)
|
||||||
|
- [GbkToUtf8](#GbkToUtf8)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ColorHexToRGB">ColorHexToRGB</span>
|
### <span id="ColorHexToRGB">ColorHexToRGB</span>
|
||||||
|
|
||||||
<p>Convert color hex to color rgb.</p>
|
<p>Convert color hex to color rgb.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -43,6 +55,7 @@ import (
|
|||||||
```go
|
```go
|
||||||
func ColorHexToRGB(colorHex string) (red, green, blue int)
|
func ColorHexToRGB(colorHex string) (red, green, blue int)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -50,18 +63,16 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/convertor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
colorHex := "#003366"
|
colorHex := "#003366"
|
||||||
r, g, b := convertor.ColorHexToRGB(colorHex)
|
r, g, b := ColorHexToRGB(colorHex)
|
||||||
fmt.Println(r, g, b) //0,51,102
|
fmt.Println(r, g, b) //0,51,102
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ColorRGBToHex">ColorRGBToHex</span>
|
### <span id="ColorRGBToHex">ColorRGBToHex</span>
|
||||||
|
|
||||||
<p>Convert color rgb to color hex.</p>
|
<p>Convert color rgb to color hex.</p>
|
||||||
@@ -71,6 +82,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ColorRGBToHex(red, green, blue int) string
|
func ColorRGBToHex(red, green, blue int) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -78,21 +90,19 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/convertor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
r := 0
|
r := 0
|
||||||
g := 51
|
g := 51
|
||||||
b := 102
|
b := 102
|
||||||
colorHex := convertor.ColorRGBToHex(r, g, b)
|
colorHex := ColorRGBToHex(r, g, b)
|
||||||
|
|
||||||
fmt.Println(colorHex) //#003366
|
fmt.Println(colorHex) //#003366
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ToBool">ToBool</span>
|
### <span id="ToBool">ToBool</span>
|
||||||
|
|
||||||
<p>Convert string to a boolean value. Use strconv.ParseBool</p>
|
<p>Convert string to a boolean value. Use strconv.ParseBool</p>
|
||||||
@@ -102,6 +112,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToBool(s string) (bool, error)
|
func ToBool(s string) (bool, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -109,7 +120,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/convertor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -127,8 +138,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ToBytes">ToBytes</span>
|
### <span id="ToBytes">ToBytes</span>
|
||||||
|
|
||||||
<p>Convert interface to byte slice.</p>
|
<p>Convert interface to byte slice.</p>
|
||||||
@@ -136,8 +145,9 @@ func main() {
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func ToBytes(data any) ([]byte, error)
|
func ToBytes(data interface{}) ([]byte, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -145,7 +155,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/convertor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -157,8 +167,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ToChar">ToChar</span>
|
### <span id="ToChar">ToChar</span>
|
||||||
|
|
||||||
<p>Convert string to char slice.</p>
|
<p>Convert string to char slice.</p>
|
||||||
@@ -168,6 +176,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToChar(s string) []string
|
func ToChar(s string) []string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -175,7 +184,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/convertor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -190,7 +199,42 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="ToChannel">ToChannel</span>
|
||||||
|
|
||||||
|
<p>Convert a collection of elements to a read-only channels.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ToChannel(array []interface{}) <-chan interface{}
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ch := convertor.ToChannel([]int{1, 2, 3})
|
||||||
|
|
||||||
|
val1, _ := <-ch
|
||||||
|
fmt.Println(val1) //1
|
||||||
|
|
||||||
|
val2, _ := <-ch
|
||||||
|
fmt.Println(val2) //2
|
||||||
|
|
||||||
|
val3, _ := <-ch
|
||||||
|
fmt.Println(val3) //3
|
||||||
|
|
||||||
|
_, ok := <-ch
|
||||||
|
fmt.Println(ok) //false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="ToFloat">ToFloat</span>
|
### <span id="ToFloat">ToFloat</span>
|
||||||
|
|
||||||
@@ -199,8 +243,9 @@ func main() {
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func ToFloat(value any) (float64, error)
|
func ToFloat(value interface{}) (float64, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -208,7 +253,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/convertor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -223,8 +268,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ToInt">ToInt</span>
|
### <span id="ToInt">ToInt</span>
|
||||||
|
|
||||||
<p>Convert interface to a int64 value. If param is a invalid intable, will return 0 and error. </p>
|
<p>Convert interface to a int64 value. If param is a invalid intable, will return 0 and error. </p>
|
||||||
@@ -232,8 +275,9 @@ func main() {
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func ToInt(value any) (int64, error)
|
func ToInt(value interface{}) (int64, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -241,7 +285,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/convertor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -256,8 +300,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ToJson">ToJson</span>
|
### <span id="ToJson">ToJson</span>
|
||||||
|
|
||||||
<p>Convert interface to json string. If param can't be converted, will return "" and error. </p>
|
<p>Convert interface to json string. If param can't be converted, will return "" and error. </p>
|
||||||
@@ -265,8 +307,9 @@ func main() {
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func ToJson(value any) (string, error)
|
func ToJson(value interface{}) (string, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -274,7 +317,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/convertor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -284,8 +327,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ToString">ToString</span>
|
### <span id="ToString">ToString</span>
|
||||||
|
|
||||||
<p>Convert interface to string. </p>
|
<p>Convert interface to string. </p>
|
||||||
@@ -293,8 +334,9 @@ func main() {
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func ToString(value any) string
|
func ToString(value interface{}) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -302,7 +344,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/convertor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -312,8 +354,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="StructToMap">StructToMap</span>
|
### <span id="StructToMap">StructToMap</span>
|
||||||
|
|
||||||
<p>Convert struct to map, only convert exported field, struct field tag `json` should be set.</p>
|
<p>Convert struct to map, only convert exported field, struct field tag `json` should be set.</p>
|
||||||
@@ -321,8 +361,9 @@ func main() {
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func StructToMap(value any) (map[string]any, error)
|
func StructToMap(value interface{}) (map[string]interface{}, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -330,7 +371,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/convertor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -346,4 +387,303 @@ func main() {
|
|||||||
|
|
||||||
fmt.Printf("type: %T, value: %s", pm, pm) //type: map[string]interface {}, value: map[name:test]
|
fmt.Printf("type: %T, value: %s", pm, pm) //type: map[string]interface {}, value: map[name:test]
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="EncodeByte">EncodeByte</span>
|
||||||
|
|
||||||
|
<p>Encode data to byte slice.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func EncodeByte(data any) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
byteData, _ := convertor.EncodeByte("abc")
|
||||||
|
fmt.Println(byteData) //[]byte{6, 12, 0, 3, 97, 98, 99}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="DecodeByte">DecodeByte</span>
|
||||||
|
|
||||||
|
<p>Decode byte data to target object. target should be a pointer instance.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func DecodeByte(data []byte, target any) error
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var result string
|
||||||
|
byteData := []byte{6, 12, 0, 3, 97, 98, 99}
|
||||||
|
convertor.DecodeByte(byteData, &result)
|
||||||
|
fmt.Println(result) //"abc"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="DeepClone">DeepClone</span>
|
||||||
|
|
||||||
|
<p>Creates a deep copy of passed item, can't clone unexported field of struct.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func DeepClone[T any](src T) T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
type Struct struct {
|
||||||
|
Str string
|
||||||
|
Int int
|
||||||
|
Float float64
|
||||||
|
Bool bool
|
||||||
|
Nil interface{}
|
||||||
|
unexported string
|
||||||
|
}
|
||||||
|
|
||||||
|
cases := []interface{}{
|
||||||
|
true,
|
||||||
|
1,
|
||||||
|
0.1,
|
||||||
|
map[string]int{
|
||||||
|
"a": 1,
|
||||||
|
"b": 2,
|
||||||
|
},
|
||||||
|
&Struct{
|
||||||
|
Str: "test",
|
||||||
|
Int: 1,
|
||||||
|
Float: 0.1,
|
||||||
|
Bool: true,
|
||||||
|
Nil: nil,
|
||||||
|
// unexported: "can't be cloned",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range cases {
|
||||||
|
cloned := convertor.DeepClone(item)
|
||||||
|
|
||||||
|
isPointerEqual := &cloned == &item
|
||||||
|
fmt.Println(cloned, isPointerEqual)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true false
|
||||||
|
// 1 false
|
||||||
|
// 0.1 false
|
||||||
|
// map[a:1 b:2] false
|
||||||
|
// &{test 1 0.1 true <nil> } false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="CopyProperties">CopyProperties</span>
|
||||||
|
|
||||||
|
<p>Copies each field from the source struct into the destination struct. Use json.Marshal/Unmarshal, so json tag should be set for fields of dst and src struct.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func CopyProperties(dst, src interface{}) error
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
type Disk struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Total string `json:"total"`
|
||||||
|
Used string `json:"used"`
|
||||||
|
Percent float64 `json:"percent"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DiskVO struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Total string `json:"total"`
|
||||||
|
Used string `json:"used"`
|
||||||
|
Percent float64 `json:"percent"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Indicator struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
Ip string `json:"ip"`
|
||||||
|
UpTime string `json:"upTime"`
|
||||||
|
LoadAvg string `json:"loadAvg"`
|
||||||
|
Cpu int `json:"cpu"`
|
||||||
|
Disk []Disk `json:"disk"`
|
||||||
|
Stop chan bool `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type IndicatorVO struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
Ip string `json:"ip"`
|
||||||
|
UpTime string `json:"upTime"`
|
||||||
|
LoadAvg string `json:"loadAvg"`
|
||||||
|
Cpu int64 `json:"cpu"`
|
||||||
|
Disk []DiskVO `json:"disk"`
|
||||||
|
}
|
||||||
|
|
||||||
|
indicator := &Indicator{Id: "001", Ip: "127.0.0.1", Cpu: 1, Disk: []Disk{
|
||||||
|
{Name: "disk-001", Total: "100", Used: "1", Percent: 10},
|
||||||
|
{Name: "disk-002", Total: "200", Used: "1", Percent: 20},
|
||||||
|
{Name: "disk-003", Total: "300", Used: "1", Percent: 30},
|
||||||
|
}}
|
||||||
|
|
||||||
|
indicatorVO := IndicatorVO{}
|
||||||
|
|
||||||
|
err := convertor.CopyProperties(&indicatorVO, indicator)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(indicatorVO.Id)
|
||||||
|
fmt.Println(indicatorVO.Ip)
|
||||||
|
fmt.Println(len(indicatorVO.Disk))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 001
|
||||||
|
// 127.0.0.1
|
||||||
|
// 3
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="ToInterface">ToInterface</span>
|
||||||
|
|
||||||
|
<p>Converts reflect value to its interface type.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ToInterface(v reflect.Value) (value interface{}, ok bool)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
val := reflect.ValueOf("abc")
|
||||||
|
iVal, ok := convertor.ToInterface(val)
|
||||||
|
|
||||||
|
fmt.Printf("%T\n", iVal)
|
||||||
|
fmt.Printf("%v\n", iVal)
|
||||||
|
fmt.Println(ok)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// string
|
||||||
|
// abc
|
||||||
|
// true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Utf8ToGbk">Utf8ToGbk</span>
|
||||||
|
|
||||||
|
<p>Converts utf8 encoding data to GBK encoding data.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Utf8ToGbk(bs []byte) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/convertor"
|
||||||
|
"github.com/duke-git/lancet/validator"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
utf8Data := []byte("hello")
|
||||||
|
gbkData, _ := convertor.Utf8ToGbk(utf8Data)
|
||||||
|
|
||||||
|
fmt.Println(utf8.Valid(utf8Data))
|
||||||
|
fmt.Println(validator.IsGBK(gbkData))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="GbkToUtf8">GbkToUtf8</span>
|
||||||
|
|
||||||
|
<p>Converts GBK encoding data to utf8 encoding data.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GbkToUtf8(bs []byte) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
gbkData, _ := convertor.Utf8ToGbk([]byte("hello"))
|
||||||
|
utf8Data, _ := convertor.GbkToUtf8(gbkData)
|
||||||
|
|
||||||
|
fmt.Println(utf8.Valid(utf8Data))
|
||||||
|
fmt.Println(string(utf8Data))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// hello
|
||||||
|
}
|
||||||
```
|
```
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
# Convertor
|
# Convertor
|
||||||
convertor转换器包支持一些常见的数据类型转换
|
|
||||||
|
convertor 转换器包支持一些常见的数据类型转换
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 源码:
|
## 源码:
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/convertor/convertor.go](https://github.com/duke-git/lancet/blob/main/convertor/convertor.go)
|
[https://github.com/duke-git/lancet/blob/v1/convertor/convertor.go](https://github.com/duke-git/lancet/blob/v1/convertor/convertor.go)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
@@ -13,7 +14,7 @@ convertor转换器包支持一些常见的数据类型转换
|
|||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/convertor"
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -21,23 +22,31 @@ import (
|
|||||||
|
|
||||||
## 目录
|
## 目录
|
||||||
|
|
||||||
- [ColorHexToRGB](#ColorHexToRGB)
|
- [ColorHexToRGB](#ColorHexToRGB)
|
||||||
- [ColorRGBToHex](#ColorRGBToHex)
|
- [ColorRGBToHex](#ColorRGBToHex)
|
||||||
- [ToBool](#ToBool)
|
- [ToBool](#ToBool)
|
||||||
- [ToBytes](#ToBytes)
|
- [ToBytes](#ToBytes)
|
||||||
- [ToChar](#ToChar)
|
- [ToChar](#ToChar)
|
||||||
- [ToInt](#ToInt)
|
- [ToChannel](#ToChannel)
|
||||||
- [ToJson](#ToJson)
|
- [ToFloat](#ToFloat)
|
||||||
- [ToString](#ToString)
|
- [ToInt](#ToInt)
|
||||||
- [StructToMap](#StructToMap)
|
- [ToJson](#ToJson)
|
||||||
|
- [ToString](#ToString)
|
||||||
|
- [StructToMap](#StructToMap)
|
||||||
|
- [EncodeByte](#EncodeByte)
|
||||||
|
- [DecodeByte](#DecodeByte)
|
||||||
|
- [DeepClone](#DeepClone)
|
||||||
|
- [CopyProperties](#CopyProperties)
|
||||||
|
- [ToInterface](#ToInterface)
|
||||||
|
- [Utf8ToGbk](#Utf8ToGbk)
|
||||||
|
- [GbkToUtf8](#GbkToUtf8)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 文档
|
## 文档
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ColorHexToRGB">ColorHexToRGB</span>
|
### <span id="ColorHexToRGB">ColorHexToRGB</span>
|
||||||
|
|
||||||
<p>颜色值十六进制转rgb</p>
|
<p>颜色值十六进制转rgb</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -45,6 +54,7 @@ import (
|
|||||||
```go
|
```go
|
||||||
func ColorHexToRGB(colorHex string) (red, green, blue int)
|
func ColorHexToRGB(colorHex string) (red, green, blue int)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>列子:</b>
|
<b>列子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -52,18 +62,16 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/convertor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
colorHex := "#003366"
|
colorHex := "#003366"
|
||||||
r, g, b := convertor.ColorHexToRGB(colorHex)
|
r, g, b := ColorHexToRGB(colorHex)
|
||||||
fmt.Println(r, g, b) //0,51,102
|
fmt.Println(r, g, b) //0,51,102
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ColorRGBToHex">ColorRGBToHex</span>
|
### <span id="ColorRGBToHex">ColorRGBToHex</span>
|
||||||
|
|
||||||
<p>颜色值rgb转十六进制</p>
|
<p>颜色值rgb转十六进制</p>
|
||||||
@@ -73,6 +81,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ColorRGBToHex(red, green, blue int) string
|
func ColorRGBToHex(red, green, blue int) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>列子:</b>
|
<b>列子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -80,21 +89,19 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/convertor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
r := 0
|
r := 0
|
||||||
g := 51
|
g := 51
|
||||||
b := 102
|
b := 102
|
||||||
colorHex := convertor.ColorRGBToHex(r, g, b)
|
colorHex := ColorRGBToHex(r, g, b)
|
||||||
|
|
||||||
fmt.Println(colorHex) //#003366
|
fmt.Println(colorHex) //#003366
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ToBool">ToBool</span>
|
### <span id="ToBool">ToBool</span>
|
||||||
|
|
||||||
<p>字符串转布尔类型,使用strconv.ParseBool</p>
|
<p>字符串转布尔类型,使用strconv.ParseBool</p>
|
||||||
@@ -104,6 +111,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToBool(s string) (bool, error)
|
func ToBool(s string) (bool, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>列子:</b>
|
<b>列子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -111,7 +119,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/convertor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -129,8 +137,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ToBytes">ToBytes</span>
|
### <span id="ToBytes">ToBytes</span>
|
||||||
|
|
||||||
<p>interface转字节切片.</p>
|
<p>interface转字节切片.</p>
|
||||||
@@ -138,8 +144,9 @@ func main() {
|
|||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func ToBytes(data any) ([]byte, error)
|
func ToBytes(data interface{}) ([]byte, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>列子:</b>
|
<b>列子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -147,7 +154,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/convertor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -159,8 +166,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ToChar">ToChar</span>
|
### <span id="ToChar">ToChar</span>
|
||||||
|
|
||||||
<p>字符串转字符切片</p>
|
<p>字符串转字符切片</p>
|
||||||
@@ -170,6 +175,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ToChar(s string) []string
|
func ToChar(s string) []string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>列子:</b>
|
<b>列子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -177,7 +183,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/convertor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -192,7 +198,42 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="ToChannel">ToChannel</span>
|
||||||
|
|
||||||
|
<p>将切片转为只读channel</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ToChannel(array []interface{}) <-chan interface{}
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ch := convertor.ToChannel([]int{1, 2, 3})
|
||||||
|
|
||||||
|
val1, _ := <-ch
|
||||||
|
fmt.Println(val1) //1
|
||||||
|
|
||||||
|
val2, _ := <-ch
|
||||||
|
fmt.Println(val2) //2
|
||||||
|
|
||||||
|
val3, _ := <-ch
|
||||||
|
fmt.Println(val3) //3
|
||||||
|
|
||||||
|
_, ok := <-ch
|
||||||
|
fmt.Println(ok) //false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="ToFloat">ToFloat</span>
|
### <span id="ToFloat">ToFloat</span>
|
||||||
|
|
||||||
@@ -201,8 +242,9 @@ func main() {
|
|||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func ToFloat(value any) (float64, error)
|
func ToFloat(value interface{}) (float64, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>列子:</b>
|
<b>列子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -210,7 +252,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/convertor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -225,8 +267,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ToInt">ToInt</span>
|
### <span id="ToInt">ToInt</span>
|
||||||
|
|
||||||
<p>将interface转成intt64类型,如果参数无法转换,会返回0和error</p>
|
<p>将interface转成intt64类型,如果参数无法转换,会返回0和error</p>
|
||||||
@@ -234,8 +274,9 @@ func main() {
|
|||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func ToInt(value any) (int64, error)
|
func ToInt(value interface{}) (int64, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -243,7 +284,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/convertor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -258,8 +299,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ToJson">ToJson</span>
|
### <span id="ToJson">ToJson</span>
|
||||||
|
|
||||||
<p>将interface转成json字符串,如果参数无法转换,会返回""和error</p>
|
<p>将interface转成json字符串,如果参数无法转换,会返回""和error</p>
|
||||||
@@ -267,8 +306,9 @@ func main() {
|
|||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func ToJson(value any) (string, error)
|
func ToJson(value interface{}) (string, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>列子:</b>
|
<b>列子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -276,7 +316,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/convertor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -286,8 +326,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ToString">ToString</span>
|
### <span id="ToString">ToString</span>
|
||||||
|
|
||||||
<p>将interface转成字符串</p>
|
<p>将interface转成字符串</p>
|
||||||
@@ -295,8 +333,9 @@ func main() {
|
|||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func ToString(value any) string
|
func ToString(value interface{}) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -304,7 +343,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/convertor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -314,8 +353,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="StructToMap">StructToMap</span>
|
### <span id="StructToMap">StructToMap</span>
|
||||||
|
|
||||||
<p>将struct转成map,只会转换struct中可导出的字段。struct中导出字段需要设置json tag标记</p>
|
<p>将struct转成map,只会转换struct中可导出的字段。struct中导出字段需要设置json tag标记</p>
|
||||||
@@ -323,8 +360,9 @@ func main() {
|
|||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func StructToMap(value any) (map[string]any, error)
|
func StructToMap(value interface{}) (map[string]interface{}, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>列子:</b>
|
<b>列子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -332,7 +370,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/convertor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -348,4 +386,304 @@ func main() {
|
|||||||
|
|
||||||
fmt.Printf("type: %T, value: %s", pm, pm) //type: map[string]interface {}, value: map[name:test]
|
fmt.Printf("type: %T, value: %s", pm, pm) //type: map[string]interface {}, value: map[name:test]
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="EncodeByte">EncodeByte</span>
|
||||||
|
|
||||||
|
<p>将data编码成字节切片</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func EncodeByte(data any) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
byteData, _ := convertor.EncodeByte("abc")
|
||||||
|
fmt.Println(byteData) //[]byte{6, 12, 0, 3, 97, 98, 99}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="DecodeByte">DecodeByte</span>
|
||||||
|
|
||||||
|
<p>解码字节切片到目标对象,目标对象需要传入一个指针实例子</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func DecodeByte(data []byte, target any) error
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var result string
|
||||||
|
byteData := []byte{6, 12, 0, 3, 97, 98, 99}
|
||||||
|
convertor.DecodeByte(byteData, &result)
|
||||||
|
fmt.Println(result) //"abc"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="DeepClone">DeepClone</span>
|
||||||
|
|
||||||
|
<p>创建一个传入值的深拷贝, 无法克隆结构体的非导出字段。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func DeepClone[T any](src T) T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
type Struct struct {
|
||||||
|
Str string
|
||||||
|
Int int
|
||||||
|
Float float64
|
||||||
|
Bool bool
|
||||||
|
Nil interface{}
|
||||||
|
unexported string
|
||||||
|
}
|
||||||
|
|
||||||
|
cases := []interface{}{
|
||||||
|
true,
|
||||||
|
1,
|
||||||
|
0.1,
|
||||||
|
map[string]int{
|
||||||
|
"a": 1,
|
||||||
|
"b": 2,
|
||||||
|
},
|
||||||
|
&Struct{
|
||||||
|
Str: "test",
|
||||||
|
Int: 1,
|
||||||
|
Float: 0.1,
|
||||||
|
Bool: true,
|
||||||
|
Nil: nil,
|
||||||
|
// unexported: "can't be cloned",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range cases {
|
||||||
|
cloned := convertor.DeepClone(item)
|
||||||
|
|
||||||
|
isPointerEqual := &cloned == &item
|
||||||
|
fmt.Println(cloned, isPointerEqual)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true false
|
||||||
|
// 1 false
|
||||||
|
// 0.1 false
|
||||||
|
// map[a:1 b:2] false
|
||||||
|
// &{test 1 0.1 true <nil> } false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="CopyProperties">CopyProperties</span>
|
||||||
|
|
||||||
|
<p>拷贝不同结构体之间的同名字段。使用json.Marshal序列化,需要设置dst和src struct字段的json tag。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func CopyProperties(dst, src interface{}) error
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
type Disk struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Total string `json:"total"`
|
||||||
|
Used string `json:"used"`
|
||||||
|
Percent float64 `json:"percent"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DiskVO struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Total string `json:"total"`
|
||||||
|
Used string `json:"used"`
|
||||||
|
Percent float64 `json:"percent"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Indicator struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
Ip string `json:"ip"`
|
||||||
|
UpTime string `json:"upTime"`
|
||||||
|
LoadAvg string `json:"loadAvg"`
|
||||||
|
Cpu int `json:"cpu"`
|
||||||
|
Disk []Disk `json:"disk"`
|
||||||
|
Stop chan bool `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type IndicatorVO struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
Ip string `json:"ip"`
|
||||||
|
UpTime string `json:"upTime"`
|
||||||
|
LoadAvg string `json:"loadAvg"`
|
||||||
|
Cpu int64 `json:"cpu"`
|
||||||
|
Disk []DiskVO `json:"disk"`
|
||||||
|
}
|
||||||
|
|
||||||
|
indicator := &Indicator{Id: "001", Ip: "127.0.0.1", Cpu: 1, Disk: []Disk{
|
||||||
|
{Name: "disk-001", Total: "100", Used: "1", Percent: 10},
|
||||||
|
{Name: "disk-002", Total: "200", Used: "1", Percent: 20},
|
||||||
|
{Name: "disk-003", Total: "300", Used: "1", Percent: 30},
|
||||||
|
}}
|
||||||
|
|
||||||
|
indicatorVO := IndicatorVO{}
|
||||||
|
|
||||||
|
err := convertor.CopyProperties(&indicatorVO, indicator)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(indicatorVO.Id)
|
||||||
|
fmt.Println(indicatorVO.Ip)
|
||||||
|
fmt.Println(len(indicatorVO.Disk))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 001
|
||||||
|
// 127.0.0.1
|
||||||
|
// 3
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="ToInterface">ToInterface</span>
|
||||||
|
|
||||||
|
<p>将反射值转换成对应的interface类型。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ToInterface(v reflect.Value) (value interface{}, ok bool)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
val := reflect.ValueOf("abc")
|
||||||
|
iVal, ok := convertor.ToInterface(val)
|
||||||
|
|
||||||
|
fmt.Printf("%T\n", iVal)
|
||||||
|
fmt.Printf("%v\n", iVal)
|
||||||
|
fmt.Println(ok)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// string
|
||||||
|
// abc
|
||||||
|
// true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Utf8ToGbk">Utf8ToGbk</span>
|
||||||
|
|
||||||
|
<p>utf8编码转GBK编码。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Utf8ToGbk(bs []byte) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/convertor"
|
||||||
|
"github.com/duke-git/lancet/validator"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
utf8Data := []byte("hello")
|
||||||
|
gbkData, _ := convertor.Utf8ToGbk(utf8Data)
|
||||||
|
|
||||||
|
fmt.Println(utf8.Valid(utf8Data))
|
||||||
|
fmt.Println(validator.IsGBK(gbkData))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="GbkToUtf8">GbkToUtf8</span>
|
||||||
|
|
||||||
|
<p>GBK编码转utf8编码。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GbkToUtf8(bs []byte) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
gbkData, _ := convertor.Utf8ToGbk([]byte("hello"))
|
||||||
|
utf8Data, _ := convertor.GbkToUtf8(gbkData)
|
||||||
|
|
||||||
|
fmt.Println(utf8.Valid(utf8Data))
|
||||||
|
fmt.Println(string(utf8Data))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// hello
|
||||||
|
}
|
||||||
```
|
```
|
||||||
334
docs/cryptor.md
334
docs/cryptor.md
@@ -1,21 +1,23 @@
|
|||||||
# Cryptor
|
# Cryptor
|
||||||
|
|
||||||
Package cryptor contains some functions for data encryption and decryption. Support base64, md5, hmac, aes, des, rsa.
|
Package cryptor contains some functions for data encryption and decryption. Support base64, md5, hmac, aes, des, rsa.
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Source:
|
## Source:
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/cryptor/aes.go](https://github.com/duke-git/lancet/blob/main/cryptor/aes.go)
|
- [https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go](https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go)
|
||||||
- [https://github.com/duke-git/lancet/blob/main/cryptor/des.go](https://github.com/duke-git/lancet/blob/main/cryptor/des.go)
|
- [https://github.com/duke-git/lancet/blob/v1/cryptor/des.go](https://github.com/duke-git/lancet/blob/v1/cryptor/des.go)
|
||||||
- [https://github.com/duke-git/lancet/blob/main/cryptor/basic.go](https://github.com/duke-git/lancet/blob/main/cryptor/basic.go)
|
- [https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go](https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go)
|
||||||
- [https://github.com/duke-git/lancet/blob/main/cryptor/rsa.go](https://github.com/duke-git/lancet/blob/main/cryptor/rsa.go)
|
- [https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go](https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Usage:
|
## Usage:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -23,47 +25,43 @@ import (
|
|||||||
|
|
||||||
## Index
|
## Index
|
||||||
|
|
||||||
- [AesEcbEncrypt](#AesEcbEncrypt)
|
- [AesEcbEncrypt](#AesEcbEncrypt)
|
||||||
- [AesEcbDecrypt](#AesEcbDecrypt)
|
- [AesEcbDecrypt](#AesEcbDecrypt)
|
||||||
- [AesCbcEncrypt](#AesCbcEncrypt)
|
- [AesCbcEncrypt](#AesCbcEncrypt)
|
||||||
- [AesCbcDecrypt](#AesCbcDecrypt)
|
- [AesCbcDecrypt](#AesCbcDecrypt)
|
||||||
- [AesCtrCrypt](#AesCtrCrypt)
|
- [AesCtrCrypt](#AesCtrCrypt)
|
||||||
- [AesCfbEncrypt](#AesCfbEncrypt)
|
- [AesCfbEncrypt](#AesCfbEncrypt)
|
||||||
- [AesCfbDecrypt](#AesCfbDecrypt)
|
- [AesCfbDecrypt](#AesCfbDecrypt)
|
||||||
- [AesOfbEncrypt](#AesOfbEncrypt)
|
- [AesOfbEncrypt](#AesOfbEncrypt)
|
||||||
- [AesOfbDecrypt](#AesOfbDecrypt)
|
- [AesOfbDecrypt](#AesOfbDecrypt)
|
||||||
- [Base64StdEncode](#Base64StdEncode)
|
- [Base64StdEncode](#Base64StdEncode)
|
||||||
- [Base64StdDecode](#Base64StdDecode)
|
- [Base64StdDecode](#Base64StdDecode)
|
||||||
- [DesEcbEncrypt](#DesEcbEncrypt)
|
- [DesEcbEncrypt](#DesEcbEncrypt)
|
||||||
- [DesEcbDecrypt](#DesEcbDecrypt)
|
- [DesEcbDecrypt](#DesEcbDecrypt)
|
||||||
- [DesCbcEncrypt](#DesCbcEncrypt)
|
- [DesCbcEncrypt](#DesCbcEncrypt)
|
||||||
- [DesCbcDecrypt](#DesCbcDecrypt)
|
- [DesCbcDecrypt](#DesCbcDecrypt)
|
||||||
- [DesCtrCrypt](#DesCtrCrypt)
|
- [DesCtrCrypt](#DesCtrCrypt)
|
||||||
- [DesCfbEncrypt](#DesCfbEncrypt)
|
- [DesCfbEncrypt](#DesCfbEncrypt)
|
||||||
- [DesCfbDecrypt](#DesCfbDecrypt)
|
- [DesCfbDecrypt](#DesCfbDecrypt)
|
||||||
- [DesOfbEncrypt](#DesOfbEncrypt)
|
- [DesOfbEncrypt](#DesOfbEncrypt)
|
||||||
- [DesOfbDecrypt](#DesOfbDecrypt)
|
- [DesOfbDecrypt](#DesOfbDecrypt)
|
||||||
- [HmacMd5](#HmacMd5)
|
- [HmacMd5](#HmacMd5)
|
||||||
- [HmacSha1](#HmacSha1)
|
- [HmacSha1](#HmacSha1)
|
||||||
- [HmacSha256](#HmacSha256)
|
- [HmacSha256](#HmacSha256)
|
||||||
- [HmacSha512](#HmacSha512)
|
- [HmacSha512](#HmacSha512)
|
||||||
|
- [Md5String](#Md5String)
|
||||||
- [Md5String](#Md5String)
|
- [Md5File](#Md5File)
|
||||||
- [Md5File](#Md5File)
|
- [Sha1](#Sha1)
|
||||||
- [Sha1](#Sha1)
|
- [Sha256](#Sha256)
|
||||||
- [Sha256](#Sha256)
|
- [Sha512](#Sha512)
|
||||||
- [Sha512](#Sha512)
|
- [GenerateRsaKey](#GenerateRsaKey)
|
||||||
- [GenerateRsaKey](#GenerateRsaKey)
|
- [RsaEncrypt](#RsaEncrypt)
|
||||||
- [RsaEncrypt](#RsaEncrypt)
|
- [RsaDecrypt](#RsaDecrypt)
|
||||||
- [RsaDecrypt](#RsaDecrypt)
|
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="AesEcbEncrypt">AesEcbEncrypt</span>
|
### <span id="AesEcbEncrypt">AesEcbEncrypt</span>
|
||||||
|
|
||||||
<p>Encrypt data with key use AES ECB algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
<p>Encrypt data with key use AES ECB algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
||||||
@@ -73,6 +71,7 @@ import (
|
|||||||
```go
|
```go
|
||||||
func AesEcbEncrypt(data, key []byte) []byte
|
func AesEcbEncrypt(data, key []byte) []byte
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -80,20 +79,18 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefghijklmnop"
|
key := "abcdefghijklmnop"
|
||||||
encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key))
|
||||||
|
|
||||||
fmt.Println(string(encrypted))
|
fmt.Println(string(encrypted))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="AesEcbDecrypt">AesEcbDecrypt</span>
|
### <span id="AesEcbDecrypt">AesEcbDecrypt</span>
|
||||||
|
|
||||||
<p>Decrypt data with key use AES ECB algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
<p>Decrypt data with key use AES ECB algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
||||||
@@ -103,6 +100,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func AesEcbDecrypt(encrypted, key []byte) []byte
|
func AesEcbDecrypt(encrypted, key []byte) []byte
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -110,20 +108,18 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefghijklmnop"
|
key := "abcdefghijklmnop"
|
||||||
encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key))
|
||||||
decrypted := cryptor.AesEcbDecrypt(encrypted, []byte(key))
|
decrypted := cryptor.AesEcbDecrypt(encrypted, []byte(key))
|
||||||
fmt.Println(string(decrypted)) //hello world
|
fmt.Println(string(decrypted)) //hello world
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="AesCbcEncrypt">AesCbcEncrypt</span>
|
### <span id="AesCbcEncrypt">AesCbcEncrypt</span>
|
||||||
|
|
||||||
<p>Encrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
<p>Encrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
||||||
@@ -133,6 +129,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func AesCbcEncrypt(data, key []byte) []byte
|
func AesCbcEncrypt(data, key []byte) []byte
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -140,20 +137,18 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefghijklmnop"
|
key := "abcdefghijklmnop"
|
||||||
encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
|
||||||
|
|
||||||
fmt.Println(string(encrypted))
|
fmt.Println(string(encrypted))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="AesCbcDecrypt">AesCbcDecrypt</span>
|
### <span id="AesCbcDecrypt">AesCbcDecrypt</span>
|
||||||
|
|
||||||
<p>Decrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
<p>Decrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
||||||
@@ -171,20 +166,18 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefghijklmnop"
|
key := "abcdefghijklmnop"
|
||||||
encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
|
||||||
decrypted := cryptor.AesCbcDecrypt(encrypted, []byte(key))
|
decrypted := cryptor.AesCbcDecrypt(encrypted, []byte(key))
|
||||||
fmt.Println(string(decrypted)) //hello world
|
fmt.Println(string(decrypted)) //hello world
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="AesCtrCrypt">AesCtrCrypt</span>
|
### <span id="AesCtrCrypt">AesCtrCrypt</span>
|
||||||
|
|
||||||
<p>Encrypt or decrypt data with key use AES CTR algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
<p>Encrypt or decrypt data with key use AES CTR algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
||||||
@@ -202,12 +195,12 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefghijklmnop"
|
key := "abcdefghijklmnop"
|
||||||
encrypted := cryptor.AesCtrCrypt([]byte(data), []byte(key))
|
encrypted := cryptor.AesCtrCrypt([]byte(data), []byte(key))
|
||||||
decrypted := cryptor.AesCtrCrypt(encrypted, []byte(key))
|
decrypted := cryptor.AesCtrCrypt(encrypted, []byte(key))
|
||||||
|
|
||||||
@@ -215,8 +208,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="AesCfbEncrypt">AesCfbEncrypt</span>
|
### <span id="AesCfbEncrypt">AesCfbEncrypt</span>
|
||||||
|
|
||||||
<p>Encrypt data with key use AES CFB algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
<p>Encrypt data with key use AES CFB algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
||||||
@@ -234,19 +225,17 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefghijklmnop"
|
key := "abcdefghijklmnop"
|
||||||
encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key))
|
||||||
fmt.Println(string(encrypted))
|
fmt.Println(string(encrypted))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="AesCfbDecrypt">AesCfbDecrypt</span>
|
### <span id="AesCfbDecrypt">AesCfbDecrypt</span>
|
||||||
|
|
||||||
<p>Decrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
<p>Decrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
||||||
@@ -264,20 +253,18 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefghijklmnop"
|
key := "abcdefghijklmnop"
|
||||||
encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key))
|
||||||
decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key))
|
decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key))
|
||||||
fmt.Println(string(decrypted)) //hello world
|
fmt.Println(string(decrypted)) //hello world
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="AesOfbEncrypt">AesOfbEncrypt</span>
|
### <span id="AesOfbEncrypt">AesOfbEncrypt</span>
|
||||||
|
|
||||||
<p>Enecrypt data with key use AES OFB algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
<p>Enecrypt data with key use AES OFB algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
||||||
@@ -295,19 +282,17 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefghijklmnop"
|
key := "abcdefghijklmnop"
|
||||||
encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key))
|
||||||
fmt.Println(string(encrypted))
|
fmt.Println(string(encrypted))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="AesCfbDecrypt">AesOfbDecrypt</span>
|
### <span id="AesCfbDecrypt">AesOfbDecrypt</span>
|
||||||
|
|
||||||
<p>Decrypt data with key use AES OFB algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
<p>Decrypt data with key use AES OFB algorithm. Length of `key` param should be 16, 24 or 32.</p>
|
||||||
@@ -325,21 +310,19 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefghijklmnop"
|
key := "abcdefghijklmnop"
|
||||||
encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key))
|
||||||
decrypted := cryptor.AesOfbDecrypt(encrypted, []byte(key))
|
decrypted := cryptor.AesOfbDecrypt(encrypted, []byte(key))
|
||||||
|
|
||||||
fmt.Println(string(decrypted)) //hello world
|
fmt.Println(string(decrypted)) //hello world
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Base64StdEncode">Base64StdEncode</span>
|
### <span id="Base64StdEncode">Base64StdEncode</span>
|
||||||
|
|
||||||
<p>Encode string with base64 encoding.</p>
|
<p>Encode string with base64 encoding.</p>
|
||||||
@@ -349,6 +332,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Base64StdEncode(s string) string
|
func Base64StdEncode(s string) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -356,17 +340,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
base64Str := cryptor.Base64StdEncode("hello world")
|
base64Str := cryptor.Base64StdEncode("hello world")
|
||||||
fmt.Println(base64Str) //aGVsbG8gd29ybGQ=
|
fmt.Println(base64Str) //aGVsbG8gd29ybGQ=
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Base64StdDecode">Base64StdDecode</span>
|
### <span id="Base64StdDecode">Base64StdDecode</span>
|
||||||
|
|
||||||
<p>Decode a base64 encoded string.</p>
|
<p>Decode a base64 encoded string.</p>
|
||||||
@@ -384,7 +366,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -393,8 +375,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="DesEcbEncrypt">DesEcbEncrypt</span>
|
### <span id="DesEcbEncrypt">DesEcbEncrypt</span>
|
||||||
|
|
||||||
<p>Encrypt data with key use DES ECB algorithm. Length of `key` param should be 8.</p>
|
<p>Encrypt data with key use DES ECB algorithm. Length of `key` param should be 8.</p>
|
||||||
@@ -412,20 +392,18 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefgh"
|
key := "abcdefgh"
|
||||||
encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key))
|
||||||
|
|
||||||
fmt.Println(string(encrypted))
|
fmt.Println(string(encrypted))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="DesEcbDecrypt">DesEcbDecrypt</span>
|
### <span id="DesEcbDecrypt">DesEcbDecrypt</span>
|
||||||
|
|
||||||
<p>Decrypt data with key use DES ECB algorithm. Length of `key` param should be 8.</p>
|
<p>Decrypt data with key use DES ECB algorithm. Length of `key` param should be 8.</p>
|
||||||
@@ -443,21 +421,19 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefgh"
|
key := "abcdefgh"
|
||||||
encrypted := cryptor.DesEcbEncrypt([]byte(data), []byt(key)
|
encrypted := cryptor.DesEcbEncrypt([]byte(data), []byt(key)
|
||||||
decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key))
|
decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key))
|
||||||
|
|
||||||
fmt.Println(string(decrypted)) //hello world
|
fmt.Println(string(decrypted)) //hello world
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="DesCbcEncrypt">DesCbcEncrypt</span>
|
### <span id="DesCbcEncrypt">DesCbcEncrypt</span>
|
||||||
|
|
||||||
<p>Encrypt data with key use DES CBC algorithm. Length of `key` param should be 8.</p>
|
<p>Encrypt data with key use DES CBC algorithm. Length of `key` param should be 8.</p>
|
||||||
@@ -475,20 +451,18 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefgh"
|
key := "abcdefgh"
|
||||||
encrypted := cryptor.DesCbcEncrypt([]byte(data), []byt(key)
|
encrypted := cryptor.DesCbcEncrypt([]byte(data), []byt(key)
|
||||||
|
|
||||||
fmt.Println(string(encrypted))
|
fmt.Println(string(encrypted))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="DesCbcDecrypt">DesCbcDecrypt</span>
|
### <span id="DesCbcDecrypt">DesCbcDecrypt</span>
|
||||||
|
|
||||||
<p>Decrypt data with key use DES CBC algorithm. Length of `key` param should be 8.</p>
|
<p>Decrypt data with key use DES CBC algorithm. Length of `key` param should be 8.</p>
|
||||||
@@ -506,21 +480,19 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefgh"
|
key := "abcdefgh"
|
||||||
encrypted := cryptor.DesCbcEncrypt([]byte(data), []byt(key)
|
encrypted := cryptor.DesCbcEncrypt([]byte(data), []byt(key)
|
||||||
decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key))
|
decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key))
|
||||||
|
|
||||||
fmt.Println(string(decrypted)) //hello world
|
fmt.Println(string(decrypted)) //hello world
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="DesCtrCrypt">DesCtrCrypt</span>
|
### <span id="DesCtrCrypt">DesCtrCrypt</span>
|
||||||
|
|
||||||
<p>Encrypt or decrypt data with key use DES CTR algorithm. Length of `key` param should be 8.</p>
|
<p>Encrypt or decrypt data with key use DES CTR algorithm. Length of `key` param should be 8.</p>
|
||||||
@@ -538,12 +510,12 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefgh"
|
key := "abcdefgh"
|
||||||
encrypted := cryptor.DesCtrCrypt([]byte(data), []byte(key))
|
encrypted := cryptor.DesCtrCrypt([]byte(data), []byte(key))
|
||||||
decrypted := cryptor.DesCtrCrypt(encrypted, []byte(key))
|
decrypted := cryptor.DesCtrCrypt(encrypted, []byte(key))
|
||||||
|
|
||||||
@@ -551,8 +523,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="DesCfbEncrypt">DesCfbEncrypt</span>
|
### <span id="DesCfbEncrypt">DesCfbEncrypt</span>
|
||||||
|
|
||||||
<p>Encrypt data with key use DES CFB algorithm. Length of `key` param should be 8.</p>
|
<p>Encrypt data with key use DES CFB algorithm. Length of `key` param should be 8.</p>
|
||||||
@@ -570,19 +540,17 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefgh"
|
key := "abcdefgh"
|
||||||
encrypted := cryptor.DesCfbEncrypt([]byte(data), []byt(key)
|
encrypted := cryptor.DesCfbEncrypt([]byte(data), []byt(key)
|
||||||
fmt.Println(string(encrypted))
|
fmt.Println(string(encrypted))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="DesCfbDecrypt">DesCfbDecrypt</span>
|
### <span id="DesCfbDecrypt">DesCfbDecrypt</span>
|
||||||
|
|
||||||
<p>Decrypt data with key use DES CBC algorithm. Length of `key` param should be 8.</p>
|
<p>Decrypt data with key use DES CBC algorithm. Length of `key` param should be 8.</p>
|
||||||
@@ -600,20 +568,18 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefgh"
|
key := "abcdefgh"
|
||||||
encrypted := cryptor.DesCfbEncrypt([]byte(data), []byt(key)
|
encrypted := cryptor.DesCfbEncrypt([]byte(data), []byt(key)
|
||||||
decrypted := cryptor.DesCfbDecrypt(encrypted, []byte(key))
|
decrypted := cryptor.DesCfbDecrypt(encrypted, []byte(key))
|
||||||
fmt.Println(string(decrypted)) //hello world
|
fmt.Println(string(decrypted)) //hello world
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="DesOfbEncrypt">DesOfbEncrypt</span>
|
### <span id="DesOfbEncrypt">DesOfbEncrypt</span>
|
||||||
|
|
||||||
<p>Enecrypt data with key use DES OFB algorithm. Length of `key` param should be 8.</p>
|
<p>Enecrypt data with key use DES OFB algorithm. Length of `key` param should be 8.</p>
|
||||||
@@ -631,19 +597,17 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefgh"
|
key := "abcdefgh"
|
||||||
encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key))
|
||||||
fmt.Println(string(encrypted))
|
fmt.Println(string(encrypted))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="DesOfbDecrypt">DesOfbDecrypt</span>
|
### <span id="DesOfbDecrypt">DesOfbDecrypt</span>
|
||||||
|
|
||||||
<p>Decrypt data with key use DES OFB algorithm. Length of `key` param should be 8.</p>
|
<p>Decrypt data with key use DES OFB algorithm. Length of `key` param should be 8.</p>
|
||||||
@@ -661,21 +625,19 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefgh"
|
key := "abcdefgh"
|
||||||
encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key))
|
||||||
decrypted := cryptor.DesOfbDecrypt(encrypted, []byte(key))
|
decrypted := cryptor.DesOfbDecrypt(encrypted, []byte(key))
|
||||||
|
|
||||||
fmt.Println(string(decrypted)) //hello world
|
fmt.Println(string(decrypted)) //hello world
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="HmacMd5">HmacMd5</span>
|
### <span id="HmacMd5">HmacMd5</span>
|
||||||
|
|
||||||
<p>Get the md5 hmac hash of string.</p>
|
<p>Get the md5 hmac hash of string.</p>
|
||||||
@@ -693,17 +655,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := cryptor.HmacMd5("hello world", "12345"))
|
s := cryptor.HmacMd5("hello world", "12345"))
|
||||||
fmt.Println(s) //5f4c9faaff0a1ad3007d9ddc06abe36d
|
fmt.Println(s) //5f4c9faaff0a1ad3007d9ddc06abe36d
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="HmacSha1">HmacSha1</span>
|
### <span id="HmacSha1">HmacSha1</span>
|
||||||
|
|
||||||
<p>Get the sha1 hmac hash of string.</p>
|
<p>Get the sha1 hmac hash of string.</p>
|
||||||
@@ -721,17 +681,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := cryptor.HmacSha1("hello world", "12345"))
|
s := cryptor.HmacSha1("hello world", "12345"))
|
||||||
fmt.Println(s) //3826f812255d8683f051ee97346d1359234d5dbd
|
fmt.Println(s) //3826f812255d8683f051ee97346d1359234d5dbd
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="HmacSha256">HmacSha256</span>
|
### <span id="HmacSha256">HmacSha256</span>
|
||||||
|
|
||||||
<p>Get the sha256 hmac hash of string</p>
|
<p>Get the sha256 hmac hash of string</p>
|
||||||
@@ -749,17 +707,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := cryptor.HmacSha256("hello world", "12345"))
|
s := cryptor.HmacSha256("hello world", "12345"))
|
||||||
fmt.Println(s) //9dce2609f2d67d41f74c7f9efc8ccd44370d41ad2de52982627588dfe7289ab8
|
fmt.Println(s) //9dce2609f2d67d41f74c7f9efc8ccd44370d41ad2de52982627588dfe7289ab8
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="HmacSha512">HmacSha512</span>
|
### <span id="HmacSha512">HmacSha512</span>
|
||||||
|
|
||||||
<p>Get the sha512 hmac hash of string.</p>
|
<p>Get the sha512 hmac hash of string.</p>
|
||||||
@@ -777,18 +733,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := cryptor.HmacSha512("hello world", "12345"))
|
s := cryptor.HmacSha512("hello world", "12345"))
|
||||||
fmt.Println(s)
|
fmt.Println(s) //5b1563ac4e9b49c9ada8ccb232588fc4f0c30fd12f756b3a0b95af4985c236ca60925253bae10ce2c6bf9af1c1679b51e5395ff3d2826c0a2c7c0d72225d4175
|
||||||
//5b1563ac4e9b49c9ada8ccb232588fc4f0c30fd12f756b3a0b95af4985c236ca60925253bae10ce2c6bf9af1c1679b51e5395ff3d2826c0a2c7c0d72225d4175
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Md5String">Md5String</span>
|
### <span id="Md5String">Md5String</span>
|
||||||
|
|
||||||
<p>Get the md5 value of string.</p>
|
<p>Get the md5 value of string.</p>
|
||||||
@@ -806,17 +759,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := cryptor.Md5String("hello"))
|
s := cryptor.Md5String("hello"))
|
||||||
fmt.Println(s) //5d41402abc4b2a76b9719d911017c592
|
fmt.Println(s) //5d41402abc4b2a76b9719d911017c592
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Md5File">Md5File</span>
|
### <span id="Md5File">Md5File</span>
|
||||||
|
|
||||||
<p>Get the md5 value of file.</p>
|
<p>Get the md5 value of file.</p>
|
||||||
@@ -834,17 +785,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := cryptor.Md5File("./main.go"))
|
s := cryptor.Md5File("./main.go"))
|
||||||
fmt.Println(s)
|
fmt.Println(s)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Sha1">Sha1</span>
|
### <span id="Sha1">Sha1</span>
|
||||||
|
|
||||||
<p>Get the sha1 value of string.</p>
|
<p>Get the sha1 value of string.</p>
|
||||||
@@ -862,17 +811,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := cryptor.Sha1("hello world"))
|
s := cryptor.Sha1("hello world"))
|
||||||
fmt.Println(s) //2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
|
fmt.Println(s) //2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Sha256">Sha256</span>
|
### <span id="Sha256">Sha256</span>
|
||||||
|
|
||||||
<p>Get the sha256 value of string.</p>
|
<p>Get the sha256 value of string.</p>
|
||||||
@@ -890,17 +837,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := cryptor.Sha256("hello world"))
|
s := cryptor.Sha256("hello world"))
|
||||||
fmt.Println(s) //b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
|
fmt.Println(s) //b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Sha512">Sha512</span>
|
### <span id="Sha512">Sha512</span>
|
||||||
|
|
||||||
<p>Get the sha512 value of string.</p>
|
<p>Get the sha512 value of string.</p>
|
||||||
@@ -918,17 +863,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := cryptor.Sha512("hello world"))
|
s := cryptor.Sha512("hello world"))
|
||||||
fmt.Println(s) //309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f
|
fmt.Println(s) //309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="GenerateRsaKey">GenerateRsaKey</span>
|
### <span id="GenerateRsaKey">GenerateRsaKey</span>
|
||||||
|
|
||||||
<p>Create the rsa public and private key file in current directory.</p>
|
<p>Create the rsa public and private key file in current directory.</p>
|
||||||
@@ -946,19 +889,17 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
|
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="RsaEncrypt">RsaEncrypt</span>
|
### <span id="RsaEncrypt">RsaEncrypt</span>
|
||||||
|
|
||||||
<p>Encrypt data with public key file useing ras algorithm.</p>
|
<p>Encrypt data with public key file useing ras algorithm.</p>
|
||||||
@@ -976,25 +917,23 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
|
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
data := []byte("hello world")
|
data := []byte("hello world")
|
||||||
encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
|
encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
|
||||||
decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
|
decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
|
||||||
|
|
||||||
fmt.Println(string(decrypted)) //hello world
|
fmt.Println(string(decrypted)) //hello world
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="RsaDecrypt">RsaDecrypt</span>
|
### <span id="RsaDecrypt">RsaDecrypt</span>
|
||||||
|
|
||||||
<p>Decrypt data with private key file useing ras algorithm.</p>
|
<p>Decrypt data with private key file useing ras algorithm.</p>
|
||||||
@@ -1012,22 +951,19 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
|
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
data := []byte("hello world")
|
data := []byte("hello world")
|
||||||
encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
|
encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
|
||||||
decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
|
decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
|
||||||
|
|
||||||
fmt.Println(string(decrypted)) //hello world
|
fmt.Println(string(decrypted)) //hello world
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,69 +1,67 @@
|
|||||||
# Cryptor
|
# Cryptor
|
||||||
cryptor加密包支持数据加密和解密,获取md5,hash值。支持base64, md5, hmac, aes, des, rsa。
|
|
||||||
|
cryptor 加密包支持数据加密和解密,获取 md5,hash 值。支持 base64, md5, hmac, aes, des, rsa。
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 源码:
|
## 源码:
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/cryptor/aes.go](https://github.com/duke-git/lancet/blob/main/cryptor/aes.go)
|
- [https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go](https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go)
|
||||||
- [https://github.com/duke-git/lancet/blob/main/cryptor/des.go](https://github.com/duke-git/lancet/blob/main/cryptor/des.go)
|
- [https://github.com/duke-git/lancet/blob/v1/cryptor/des.go](https://github.com/duke-git/lancet/blob/v1/cryptor/des.go)
|
||||||
- [https://github.com/duke-git/lancet/blob/main/cryptor/basic.go](https://github.com/duke-git/lancet/blob/main/cryptor/basic.go)
|
- [https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go](https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go)
|
||||||
- [https://github.com/duke-git/lancet/blob/main/cryptor/rsa.go](https://github.com/duke-git/lancet/blob/main/cryptor/rsa.go)
|
- [https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go](https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 用法:
|
## 用法:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 目录
|
## 目录
|
||||||
- [AesEcbEncrypt](#AesEcbEncrypt)
|
|
||||||
- [AesEcbDecrypt](#AesEcbDecrypt)
|
|
||||||
- [AesCbcEncrypt](#AesCbcEncrypt)
|
|
||||||
- [AesCbcDecrypt](#AesCbcDecrypt)
|
|
||||||
- [AesCtrCrypt](#AesCtrCrypt)
|
|
||||||
- [AesCfbEncrypt](#AesCfbEncrypt)
|
|
||||||
- [AesCfbDecrypt](#AesCfbDecrypt)
|
|
||||||
- [AesOfbEncrypt](#AesOfbEncrypt)
|
|
||||||
- [AesOfbDecrypt](#AesOfbDecrypt)
|
|
||||||
- [Base64StdEncode](#Base64StdEncode)
|
|
||||||
- [Base64StdDecode](#Base64StdDecode)
|
|
||||||
|
|
||||||
- [DesEcbEncrypt](#DesEcbEncrypt)
|
|
||||||
- [DesEcbDecrypt](#DesEcbDecrypt)
|
|
||||||
- [DesCbcEncrypt](#DesCbcEncrypt)
|
|
||||||
- [DesCbcDecrypt](#DesCbcDecrypt)
|
|
||||||
- [DesCtrCrypt](#DesCtrCrypt)
|
|
||||||
- [DesCfbEncrypt](#DesCfbEncrypt)
|
|
||||||
- [DesCfbDecrypt](#DesCfbDecrypt)
|
|
||||||
- [DesOfbEncrypt](#DesOfbEncrypt)
|
|
||||||
- [DesOfbDecrypt](#DesOfbDecrypt)
|
|
||||||
|
|
||||||
- [HmacMd5](#HmacMd5)
|
|
||||||
- [HmacSha1](#HmacSha1)
|
|
||||||
- [HmacSha256](#HmacSha256)
|
|
||||||
- [HmacSha512](#HmacSha512)
|
|
||||||
- [Md5String](#Md5String)
|
|
||||||
- [Md5File](#Md5File)
|
|
||||||
- [Sha1](#Sha1)
|
|
||||||
- [Sha256](#Sha256)
|
|
||||||
- [Sha512](#Sha512)
|
|
||||||
- [GenerateRsaKey](#GenerateRsaKey)
|
|
||||||
- [RsaEncrypt](#RsaEncrypt)
|
|
||||||
- [RsaDecrypt](#RsaDecrypt)
|
|
||||||
|
|
||||||
|
- [AesEcbEncrypt](#AesEcbEncrypt)
|
||||||
|
- [AesEcbDecrypt](#AesEcbDecrypt)
|
||||||
|
- [AesCbcEncrypt](#AesCbcEncrypt)
|
||||||
|
- [AesCbcDecrypt](#AesCbcDecrypt)
|
||||||
|
- [AesCtrCrypt](#AesCtrCrypt)
|
||||||
|
- [AesCfbEncrypt](#AesCfbEncrypt)
|
||||||
|
- [AesCfbDecrypt](#AesCfbDecrypt)
|
||||||
|
- [AesOfbEncrypt](#AesOfbEncrypt)
|
||||||
|
- [AesOfbDecrypt](#AesOfbDecrypt)
|
||||||
|
- [Base64StdEncode](#Base64StdEncode)
|
||||||
|
- [Base64StdDecode](#Base64StdDecode)
|
||||||
|
- [DesEcbEncrypt](#DesEcbEncrypt)
|
||||||
|
- [DesEcbDecrypt](#DesEcbDecrypt)
|
||||||
|
- [DesCbcEncrypt](#DesCbcEncrypt)
|
||||||
|
- [DesCbcDecrypt](#DesCbcDecrypt)
|
||||||
|
- [DesCtrCrypt](#DesCtrCrypt)
|
||||||
|
- [DesCfbEncrypt](#DesCfbEncrypt)
|
||||||
|
- [DesCfbDecrypt](#DesCfbDecrypt)
|
||||||
|
- [DesOfbEncrypt](#DesOfbEncrypt)
|
||||||
|
- [DesOfbDecrypt](#DesOfbDecrypt)
|
||||||
|
- [HmacMd5](#HmacMd5)
|
||||||
|
- [HmacSha1](#HmacSha1)
|
||||||
|
- [HmacSha256](#HmacSha256)
|
||||||
|
- [HmacSha512](#HmacSha512)
|
||||||
|
- [Md5String](#Md5String)
|
||||||
|
- [Md5File](#Md5File)
|
||||||
|
- [Sha1](#Sha1)
|
||||||
|
- [Sha256](#Sha256)
|
||||||
|
- [Sha512](#Sha512)
|
||||||
|
- [GenerateRsaKey](#GenerateRsaKey)
|
||||||
|
- [RsaEncrypt](#RsaEncrypt)
|
||||||
|
- [RsaDecrypt](#RsaDecrypt)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 文档
|
## 文档
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="AesEcbEncrypt">AesEcbEncrypt</span>
|
### <span id="AesEcbEncrypt">AesEcbEncrypt</span>
|
||||||
|
|
||||||
<p>使用AES ECB算法模式加密数据. 参数`key`的长度是16, 24 or 32。</p>
|
<p>使用AES ECB算法模式加密数据. 参数`key`的长度是16, 24 or 32。</p>
|
||||||
@@ -73,6 +71,7 @@ import (
|
|||||||
```go
|
```go
|
||||||
func AesEcbEncrypt(data, key []byte) []byte
|
func AesEcbEncrypt(data, key []byte) []byte
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>列子:</b>
|
<b>列子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -80,20 +79,18 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefghijklmnop"
|
key := "abcdefghijklmnop"
|
||||||
encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key))
|
||||||
|
|
||||||
fmt.Println(string(encrypted))
|
fmt.Println(string(encrypted))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="AesEcbDecrypt">AesEcbDecrypt</span>
|
### <span id="AesEcbDecrypt">AesEcbDecrypt</span>
|
||||||
|
|
||||||
<p>使用AES ECB算法模式解密数据. 参数`key`的长度是16, 24 or 32。
|
<p>使用AES ECB算法模式解密数据. 参数`key`的长度是16, 24 or 32。
|
||||||
@@ -103,6 +100,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func AesEcbDecrypt(encrypted, key []byte) []byte
|
func AesEcbDecrypt(encrypted, key []byte) []byte
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>列子:</b>
|
<b>列子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -110,20 +108,18 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefghijklmnop"
|
key := "abcdefghijklmnop"
|
||||||
encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key))
|
||||||
decrypted := cryptor.AesEcbDecrypt(encrypted, []byte(key))
|
decrypted := cryptor.AesEcbDecrypt(encrypted, []byte(key))
|
||||||
fmt.Println(string(decrypted)) //hello world
|
fmt.Println(string(decrypted)) //hello world
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="AesCbcEncrypt">AesCbcEncrypt</span>
|
### <span id="AesCbcEncrypt">AesCbcEncrypt</span>
|
||||||
|
|
||||||
<p>使用AES CBC算法模式加密数据. 参数`key`的长度是16, 24 or 32。</p>
|
<p>使用AES CBC算法模式加密数据. 参数`key`的长度是16, 24 or 32。</p>
|
||||||
@@ -133,6 +129,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func AesCbcEncrypt(data, key []byte) []byte
|
func AesCbcEncrypt(data, key []byte) []byte
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>列子:</b>
|
<b>列子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -140,20 +137,18 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefghijklmnop"
|
key := "abcdefghijklmnop"
|
||||||
encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
|
||||||
|
|
||||||
fmt.Println(string(encrypted))
|
fmt.Println(string(encrypted))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="AesCbcDecrypt">AesCbcDecrypt</span>
|
### <span id="AesCbcDecrypt">AesCbcDecrypt</span>
|
||||||
|
|
||||||
<p>使用AES CBC算法模式解密数据. 参数`key`的长度是16, 24 or 32。</p>
|
<p>使用AES CBC算法模式解密数据. 参数`key`的长度是16, 24 or 32。</p>
|
||||||
@@ -171,21 +166,19 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefghijklmnop"
|
key := "abcdefghijklmnop"
|
||||||
encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
|
||||||
decrypted := cryptor.AesCbcDecrypt(encrypted, []byte(key))
|
decrypted := cryptor.AesCbcDecrypt(encrypted, []byte(key))
|
||||||
|
|
||||||
fmt.Println(string(decrypted)) //hello world
|
fmt.Println(string(decrypted)) //hello world
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="AesCtrCrypt">AesCtrCrypt</span>
|
### <span id="AesCtrCrypt">AesCtrCrypt</span>
|
||||||
|
|
||||||
<p>使用AES CTR算法模式加密/解密数据. 参数`key`的长度是16, 24 or 32。</p>
|
<p>使用AES CTR算法模式加密/解密数据. 参数`key`的长度是16, 24 or 32。</p>
|
||||||
@@ -203,12 +196,12 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefghijklmnop"
|
key := "abcdefghijklmnop"
|
||||||
encrypted := cryptor.AesCtrCrypt([]byte(data), []byte(key))
|
encrypted := cryptor.AesCtrCrypt([]byte(data), []byte(key))
|
||||||
decrypted := cryptor.AesCtrCrypt(encrypted, []byte(key))
|
decrypted := cryptor.AesCtrCrypt(encrypted, []byte(key))
|
||||||
|
|
||||||
@@ -216,8 +209,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="AesCfbEncrypt">AesCfbEncrypt</span>
|
### <span id="AesCfbEncrypt">AesCfbEncrypt</span>
|
||||||
|
|
||||||
<p>使用AES CFB算法模式加密数据. 参数`key`的长度是16, 24 or 32。</p>
|
<p>使用AES CFB算法模式加密数据. 参数`key`的长度是16, 24 or 32。</p>
|
||||||
@@ -235,19 +226,17 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefghijklmnop"
|
key := "abcdefghijklmnop"
|
||||||
encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key))
|
||||||
fmt.Println(string(encrypted))
|
fmt.Println(string(encrypted))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="AesCfbDecrypt">AesCfbDecrypt</span>
|
### <span id="AesCfbDecrypt">AesCfbDecrypt</span>
|
||||||
|
|
||||||
<p>使用AES CFB算法模式解密数据. 参数`key`的长度是16, 24 or 32。</p>
|
<p>使用AES CFB算法模式解密数据. 参数`key`的长度是16, 24 or 32。</p>
|
||||||
@@ -265,20 +254,18 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefghijklmnop"
|
key := "abcdefghijklmnop"
|
||||||
encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key))
|
||||||
decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key))
|
decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key))
|
||||||
fmt.Println(string(decrypted)) //hello world
|
fmt.Println(string(decrypted)) //hello world
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="AesOfbEncrypt">AesOfbEncrypt</span>
|
### <span id="AesOfbEncrypt">AesOfbEncrypt</span>
|
||||||
|
|
||||||
<p>使用AES OFB算法模式加密数据. 参数`key`的长度是16, 24 or 32</p>
|
<p>使用AES OFB算法模式加密数据. 参数`key`的长度是16, 24 or 32</p>
|
||||||
@@ -296,19 +283,17 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefghijklmnop"
|
key := "abcdefghijklmnop"
|
||||||
encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key))
|
||||||
fmt.Println(string(encrypted))
|
fmt.Println(string(encrypted))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="AesCfbDecrypt">AesOfbDecrypt</span>
|
### <span id="AesCfbDecrypt">AesOfbDecrypt</span>
|
||||||
|
|
||||||
<p>使用AES OFB算法模式解密数据. 参数`key`的长度是16, 24 or 32</p>
|
<p>使用AES OFB算法模式解密数据. 参数`key`的长度是16, 24 or 32</p>
|
||||||
@@ -326,20 +311,18 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefghijklmnop"
|
key := "abcdefghijklmnop"
|
||||||
encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key))
|
||||||
decrypted := cryptor.AesOfbDecrypt(encrypted, []byte(key))
|
decrypted := cryptor.AesOfbDecrypt(encrypted, []byte(key))
|
||||||
fmt.Println(string(decrypted)) //hello world
|
fmt.Println(string(decrypted)) //hello world
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Base64StdEncode">Base64StdEncode</span>
|
### <span id="Base64StdEncode">Base64StdEncode</span>
|
||||||
|
|
||||||
<p>将字符串base64编码</p>
|
<p>将字符串base64编码</p>
|
||||||
@@ -349,6 +332,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Base64StdEncode(s string) string
|
func Base64StdEncode(s string) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>列子:</b>
|
<b>列子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -356,17 +340,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
base64Str := cryptor.Base64StdEncode("hello world")
|
base64Str := cryptor.Base64StdEncode("hello world")
|
||||||
fmt.Println(base64Str) //aGVsbG8gd29ybGQ=
|
fmt.Println(base64Str) //aGVsbG8gd29ybGQ=
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Base64StdDecode">Base64StdDecode</span>
|
### <span id="Base64StdDecode">Base64StdDecode</span>
|
||||||
|
|
||||||
<p>解码base64字符串</p>
|
<p>解码base64字符串</p>
|
||||||
@@ -384,17 +366,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
str := cryptor.Base64StdDecode("aGVsbG8gd29ybGQ=")
|
str := cryptor.Base64StdDecode("aGVsbG8gd29ybGQ=")
|
||||||
fmt.Println(str) //hello world
|
fmt.Println(str) //hello world
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="DesEcbEncrypt">DesEcbEncrypt</span>
|
### <span id="DesEcbEncrypt">DesEcbEncrypt</span>
|
||||||
|
|
||||||
<p>使用DES ECB算法模式加密数据. 参数`key`的长度是8</p>
|
<p>使用DES ECB算法模式加密数据. 参数`key`的长度是8</p>
|
||||||
@@ -412,20 +392,18 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefgh"
|
key := "abcdefgh"
|
||||||
encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key))
|
||||||
|
|
||||||
fmt.Println(string(encrypted))
|
fmt.Println(string(encrypted))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="DesEcbDecrypt">DesEcbDecrypt</span>
|
### <span id="DesEcbDecrypt">DesEcbDecrypt</span>
|
||||||
|
|
||||||
<p>使用DES ECB算法模式解密数据. 参数`key`的长度是8</p>
|
<p>使用DES ECB算法模式解密数据. 参数`key`的长度是8</p>
|
||||||
@@ -443,21 +421,19 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefgh"
|
key := "abcdefgh"
|
||||||
encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key))
|
||||||
decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key))
|
decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key))
|
||||||
|
|
||||||
fmt.Println(string(decrypted)) //hello world
|
fmt.Println(string(decrypted)) //hello world
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="DesCbcEncrypt">DesCbcEncrypt</span>
|
### <span id="DesCbcEncrypt">DesCbcEncrypt</span>
|
||||||
|
|
||||||
<p>使用DES CBC算法模式加密数据. 参数`key`的长度是8</p>
|
<p>使用DES CBC算法模式加密数据. 参数`key`的长度是8</p>
|
||||||
@@ -475,20 +451,18 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefgh"
|
key := "abcdefgh"
|
||||||
encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key))
|
||||||
|
|
||||||
fmt.Println(string(encrypted))
|
fmt.Println(string(encrypted))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="DesCbcDecrypt">DesCbcDecrypt</span>
|
### <span id="DesCbcDecrypt">DesCbcDecrypt</span>
|
||||||
|
|
||||||
<p>使用DES CBC算法模式解密数据. 参数`key`的长度是8</p>
|
<p>使用DES CBC算法模式解密数据. 参数`key`的长度是8</p>
|
||||||
@@ -506,21 +480,19 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefgh"
|
key := "abcdefgh"
|
||||||
encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key))
|
||||||
decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key))
|
decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key))
|
||||||
|
|
||||||
fmt.Println(string(decrypted)) //hello world
|
fmt.Println(string(decrypted)) //hello world
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="DesCtrCrypt">DesCtrCrypt</span>
|
### <span id="DesCtrCrypt">DesCtrCrypt</span>
|
||||||
|
|
||||||
<p>使用DES CTR算法模式加密/解密数据. 参数`key`的长度是8</p>
|
<p>使用DES CTR算法模式加密/解密数据. 参数`key`的长度是8</p>
|
||||||
@@ -538,12 +510,12 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefgh"
|
key := "abcdefgh"
|
||||||
encrypted := cryptor.DesCtrCrypt([]byte(data), []byte(key))
|
encrypted := cryptor.DesCtrCrypt([]byte(data), []byte(key))
|
||||||
decrypted := cryptor.DesCtrCrypt(encrypted, []byte(key))
|
decrypted := cryptor.DesCtrCrypt(encrypted, []byte(key))
|
||||||
|
|
||||||
@@ -551,8 +523,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="DesCfbEncrypt">DesCfbEncrypt</span>
|
### <span id="DesCfbEncrypt">DesCfbEncrypt</span>
|
||||||
|
|
||||||
<p>使用DES CFB算法模式加密数据. 参数`key`的长度是8</p>
|
<p>使用DES CFB算法模式加密数据. 参数`key`的长度是8</p>
|
||||||
@@ -570,19 +540,17 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefgh"
|
key := "abcdefgh"
|
||||||
encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key))
|
||||||
fmt.Println(string(encrypted))
|
fmt.Println(string(encrypted))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="DesCfbDecrypt">DesCfbDecrypt</span>
|
### <span id="DesCfbDecrypt">DesCfbDecrypt</span>
|
||||||
|
|
||||||
<p>使用DES CFB算法模式解密数据. 参数`key`的长度是8</p>
|
<p>使用DES CFB算法模式解密数据. 参数`key`的长度是8</p>
|
||||||
@@ -600,20 +568,18 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefgh"
|
key := "abcdefgh"
|
||||||
encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key))
|
||||||
decrypted := cryptor.DesCfbDecrypt(encrypted, []byte(key))
|
decrypted := cryptor.DesCfbDecrypt(encrypted, []byte(key))
|
||||||
fmt.Println(string(decrypted)) //hello world
|
fmt.Println(string(decrypted)) //hello world
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="DesOfbEncrypt">DesOfbEncrypt</span>
|
### <span id="DesOfbEncrypt">DesOfbEncrypt</span>
|
||||||
|
|
||||||
<p>使用DES OFB算法模式加密数据. 参数`key`的长度是8</p>
|
<p>使用DES OFB算法模式加密数据. 参数`key`的长度是8</p>
|
||||||
@@ -631,19 +597,17 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefgh"
|
key := "abcdefgh"
|
||||||
encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key))
|
||||||
fmt.Println(string(encrypted))
|
fmt.Println(string(encrypted))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="DesOfbDecrypt">DesOfbDecrypt</span>
|
### <span id="DesOfbDecrypt">DesOfbDecrypt</span>
|
||||||
|
|
||||||
<p>使用DES OFB算法模式解密数据. 参数`key`的长度是8</p>
|
<p>使用DES OFB算法模式解密数据. 参数`key`的长度是8</p>
|
||||||
@@ -661,20 +625,18 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
data := "hello world"
|
data := "hello world"
|
||||||
key := "abcdefgh"
|
key := "abcdefgh"
|
||||||
encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key))
|
encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key))
|
||||||
decrypted := cryptor.DesOfbDecrypt(encrypted, []byte(key))
|
decrypted := cryptor.DesOfbDecrypt(encrypted, []byte(key))
|
||||||
fmt.Println(string(decrypted)) //hello world
|
fmt.Println(string(decrypted)) //hello world
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="HmacMd5">HmacMd5</span>
|
### <span id="HmacMd5">HmacMd5</span>
|
||||||
|
|
||||||
<p>获取字符串md5 hmac值</p>
|
<p>获取字符串md5 hmac值</p>
|
||||||
@@ -692,17 +654,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := cryptor.HmacMd5("hello world", "12345"))
|
s := cryptor.HmacMd5("hello world", "12345"))
|
||||||
fmt.Println(s) //5f4c9faaff0a1ad3007d9ddc06abe36d
|
fmt.Println(s) //5f4c9faaff0a1ad3007d9ddc06abe36d
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="HmacSha1">HmacSha1</span>
|
### <span id="HmacSha1">HmacSha1</span>
|
||||||
|
|
||||||
<p>获取字符串sha1 hmac值</p>
|
<p>获取字符串sha1 hmac值</p>
|
||||||
@@ -720,17 +680,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := cryptor.HmacSha1("hello world", "12345"))
|
s := cryptor.HmacSha1("hello world", "12345"))
|
||||||
fmt.Println(s) //3826f812255d8683f051ee97346d1359234d5dbd
|
fmt.Println(s) //3826f812255d8683f051ee97346d1359234d5dbd
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="HmacSha256">HmacSha256</span>
|
### <span id="HmacSha256">HmacSha256</span>
|
||||||
|
|
||||||
<p>获取字符串sha256 hmac值</p>
|
<p>获取字符串sha256 hmac值</p>
|
||||||
@@ -748,17 +706,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := cryptor.HmacSha256("hello world", "12345"))
|
s := cryptor.HmacSha256("hello world", "12345"))
|
||||||
fmt.Println(s) //9dce2609f2d67d41f74c7f9efc8ccd44370d41ad2de52982627588dfe7289ab8
|
fmt.Println(s) //9dce2609f2d67d41f74c7f9efc8ccd44370d41ad2de52982627588dfe7289ab8
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="HmacSha512">HmacSha512</span>
|
### <span id="HmacSha512">HmacSha512</span>
|
||||||
|
|
||||||
<p>获取字符串sha512 hmac值</p>
|
<p>获取字符串sha512 hmac值</p>
|
||||||
@@ -776,18 +732,16 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := cryptor.HmacSha512("hello world", "12345"))
|
s := cryptor.HmacSha512("hello world", "12345"))
|
||||||
fmt.Println(s)
|
fmt.Println(s)
|
||||||
//5b1563ac4e9b49c9ada8ccb232588fc4f0c30fd12f756b3a0b95af4985c236ca60925253bae10ce2c6bf9af1c1679b51e5395ff3d2826c0a2c7c0d72225d4175
|
//5b1563ac4e9b49c9ada8ccb232588fc4f0c30fd12f756b3a0b95af4985c236ca60925253bae10ce2c6bf9af1c1679b51e5395ff3d2826c0a2c7c0d72225d4175
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Md5String">Md5String</span>
|
### <span id="Md5String">Md5String</span>
|
||||||
|
|
||||||
<p>获取字符串md5值</p>
|
<p>获取字符串md5值</p>
|
||||||
@@ -805,17 +759,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := cryptor.Md5String("hello"))
|
s := cryptor.Md5String("hello"))
|
||||||
fmt.Println(s) //5d41402abc4b2a76b9719d911017c592
|
fmt.Println(s) //5d41402abc4b2a76b9719d911017c592
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Md5File">Md5File</span>
|
### <span id="Md5File">Md5File</span>
|
||||||
|
|
||||||
<p>获取文件md5值.</p>
|
<p>获取文件md5值.</p>
|
||||||
@@ -833,17 +785,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := cryptor.Md5File("./main.go"))
|
s := cryptor.Md5File("./main.go"))
|
||||||
fmt.Println(s)
|
fmt.Println(s)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Sha1">Sha1</span>
|
### <span id="Sha1">Sha1</span>
|
||||||
|
|
||||||
<p>获取字符串sha1值</p>
|
<p>获取字符串sha1值</p>
|
||||||
@@ -861,17 +811,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := cryptor.Sha1("hello world"))
|
s := cryptor.Sha1("hello world"))
|
||||||
fmt.Println(s) //2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
|
fmt.Println(s) //2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Sha256">Sha256</span>
|
### <span id="Sha256">Sha256</span>
|
||||||
|
|
||||||
<p>获取字符串sha256值</p>
|
<p>获取字符串sha256值</p>
|
||||||
@@ -889,17 +837,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := cryptor.Sha256("hello world"))
|
s := cryptor.Sha256("hello world"))
|
||||||
fmt.Println(s) //b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
|
fmt.Println(s) //b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Sha512">Sha512</span>
|
### <span id="Sha512">Sha512</span>
|
||||||
|
|
||||||
<p>获取字符串sha512值</p>
|
<p>获取字符串sha512值</p>
|
||||||
@@ -917,17 +863,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := cryptor.Sha512("hello world"))
|
s := cryptor.Sha512("hello world"))
|
||||||
fmt.Println(s) //309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f
|
fmt.Println(s) //309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="GenerateRsaKey">GenerateRsaKey</span>
|
### <span id="GenerateRsaKey">GenerateRsaKey</span>
|
||||||
|
|
||||||
<p>在当前目录下创建rsa私钥文件和公钥文件</p>
|
<p>在当前目录下创建rsa私钥文件和公钥文件</p>
|
||||||
@@ -945,19 +889,17 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
|
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="RsaEncrypt">RsaEncrypt</span>
|
### <span id="RsaEncrypt">RsaEncrypt</span>
|
||||||
|
|
||||||
<p>用公钥文件ras加密数据</p>
|
<p>用公钥文件ras加密数据</p>
|
||||||
@@ -975,23 +917,22 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
|
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
data := []byte("hello world")
|
|
||||||
|
data := []byte("hello world")
|
||||||
encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
|
encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
|
||||||
decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
|
decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
|
||||||
fmt.Println(string(decrypted)) //hello world
|
fmt.Println(string(decrypted)) //hello world
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="RsaDecrypt">RsaDecrypt</span>
|
### <span id="RsaDecrypt">RsaDecrypt</span>
|
||||||
|
|
||||||
<p>用私钥文件rsa解密数据</p>
|
<p>用私钥文件rsa解密数据</p>
|
||||||
@@ -1009,20 +950,18 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/cryptor"
|
"github.com/duke-git/lancet/cryptor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
|
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
data := []byte("hello world")
|
|
||||||
|
data := []byte("hello world")
|
||||||
encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
|
encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
|
||||||
decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
|
decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
|
||||||
fmt.Println(string(decrypted)) //hello world
|
fmt.Println(string(decrypted)) //hello world
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
514
docs/datetime.md
514
docs/datetime.md
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
545
docs/fileutil.md
545
docs/fileutil.md
@@ -1,47 +1,59 @@
|
|||||||
# Fileutil
|
# Fileutil
|
||||||
|
|
||||||
Package fileutil implements some basic functions for file operations.
|
Package fileutil implements some basic functions for file operations.
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Source:
|
## Source:
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/fileutil/file.go](https://github.com/duke-git/lancet/blob/main/fileutil/file.go)
|
[https://github.com/duke-git/lancet/blob/v1/fileutil/file.go](https://github.com/duke-git/lancet/blob/v1/fileutil/file.go)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Usage:
|
## Usage:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Index
|
## 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)
|
- [ClearFile](#ClearFile)
|
||||||
|
- [CreateFile](#CreateFile)
|
||||||
|
- [CreateDir](#CreateDir)
|
||||||
|
- [CopyFile](#CopyFile)
|
||||||
|
- [FileMode](#FileMode)
|
||||||
|
- [MiMeType](#MiMeType)
|
||||||
|
- [IsExist](#IsExist)
|
||||||
|
- [IsLink](#IsLink)
|
||||||
|
- [IsDir](#IsDir)
|
||||||
|
- [ListFileNames](#ListFileNames)
|
||||||
|
- [RemoveFile](#RemoveFile)
|
||||||
|
- [ReadFileToString](#ReadFileToString)
|
||||||
|
- [ReadFileByLine](#ReadFileByLine)
|
||||||
|
- [Zip](#Zip)
|
||||||
|
- [UnZip](#UnZip)
|
||||||
|
- [ZipAppendEntry](#ZipAppendEntry)
|
||||||
|
- [CurrentPath](#CurrentPath)
|
||||||
|
- [IsZipFile](#IsZipFile)
|
||||||
|
- [FileSize](#FileSize)
|
||||||
|
- [MTime](#MTime)
|
||||||
|
- [Sha](#Sha)
|
||||||
|
- [ReadCsvFile](#ReadCsvFile)
|
||||||
|
- [WriteCsvFile](#WriteCsvFile)
|
||||||
|
- [WriteStringToFile](#WriteStringToFile)
|
||||||
|
- [WriteBytesToFile](#WriteBytesToFile)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ClearFile">ClearFile</span>
|
### <span id="ClearFile">ClearFile</span>
|
||||||
|
|
||||||
<p>Clear the file content, write empty string to the file.</p>
|
<p>Clear the file content, write empty string to the file.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -49,6 +61,7 @@ import (
|
|||||||
```go
|
```go
|
||||||
func ClearFile(path string) error
|
func ClearFile(path string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -56,7 +69,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -67,14 +80,16 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### <span id="CreateFile">CreateFile</span>
|
### <span id="CreateDir">CreateDir</span>
|
||||||
<p>Create file in path. return true if create succeed.</p>
|
|
||||||
|
<p>Create directory in absolute path. param `absPath` like /a/, /a/b/.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func CreateFile(path string) bool
|
func CreateDir(absPath string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -82,7 +97,33 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := fileutil.CreateDir("/a/")
|
||||||
|
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/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -91,8 +132,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="CopyFile">CopyFile</span>
|
### <span id="CopyFile">CopyFile</span>
|
||||||
|
|
||||||
<p>Copy src file to dest file. If dest file exist will overwrite it.</p>
|
<p>Copy src file to dest file. If dest file exist will overwrite it.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -100,6 +141,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func CopyFile(srcFilePath string, dstFilePath string) error
|
func CopyFile(srcFilePath string, dstFilePath string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -107,20 +149,19 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := fileutil.CopyFile("./test.txt", "./test_copy.txt")
|
err := fileutil.CopyFile("./test.txt", "./test_copy.txt")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="FileMode">FileMode</span>
|
### <span id="FileMode">FileMode</span>
|
||||||
|
|
||||||
<p>Return file mode infomation.</p>
|
<p>Return file mode infomation.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -128,6 +169,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func FileMode(path string) (fs.FileMode, error)
|
func FileMode(path string) (fs.FileMode, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -135,28 +177,28 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
mode, err := fileutil.FileMode("./test.txt")
|
mode, err := fileutil.FileMode("./test.txt")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
fmt.Println(mode)
|
fmt.Println(mode)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="MiMeType">MiMeType</span>
|
### <span id="MiMeType">MiMeType</span>
|
||||||
|
|
||||||
<p>Get file mime type, 'file' param's type should be string or *os.File.</p>
|
<p>Get file mime type, 'file' param's type should be string or *os.File.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func MiMeType(file any) string
|
func MiMeType(file interface{}) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -165,7 +207,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -178,10 +220,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="IsExist">IsExist</span>
|
### <span id="IsExist">IsExist</span>
|
||||||
|
|
||||||
<p>Checks if a file or directory exists.</p>
|
<p>Checks if a file or directory exists.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -189,6 +229,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func IsExist(path string) bool
|
func IsExist(path string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -196,7 +237,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -206,9 +247,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="IsLink">IsLink</span>
|
### <span id="IsLink">IsLink</span>
|
||||||
|
|
||||||
<p>Checks if a file is symbol link or not.</p>
|
<p>Checks if a file is symbol link or not.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -216,6 +256,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func IsLink(path string) bool
|
func IsLink(path string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -223,7 +264,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -232,16 +273,16 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="IsDir">IsDir</span>
|
### <span id="IsDir">IsDir</span>
|
||||||
|
|
||||||
<p>Checks if the path is directy or not.</p>
|
<p>Checks if the path is directy or not.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func IsDir(path string) bool
|
func IsDir(path string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -249,7 +290,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -261,9 +302,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ListFileNames">ListFileNames</span>
|
### <span id="ListFileNames">ListFileNames</span>
|
||||||
|
|
||||||
<p>List all file names in given path.</p>
|
<p>List all file names in given path.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -271,6 +311,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ListFileNames(path string) ([]string, error)
|
func ListFileNames(path string) ([]string, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -278,7 +319,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -287,9 +328,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="RemoveFile">RemoveFile</span>
|
### <span id="RemoveFile">RemoveFile</span>
|
||||||
|
|
||||||
<p>Remove the file of path.</p>
|
<p>Remove the file of path.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -297,6 +337,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func RemoveFile(path string) error
|
func RemoveFile(path string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -304,19 +345,19 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := fileutil.RemoveFile("./test.txt")
|
err := fileutil.RemoveFile("./test.txt")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="ReadFileToString">ReadFileToString</span>
|
### <span id="ReadFileToString">ReadFileToString</span>
|
||||||
|
|
||||||
<p>Return string of file content.</p>
|
<p>Return string of file content.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -324,6 +365,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ReadFileToString(path string) (string, error)
|
func ReadFileToString(path string) (string, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -332,24 +374,23 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
path := "./test.txt"
|
path := "./test.txt"
|
||||||
fileutil.CreateFile(path)
|
fileutil.CreateFile(path)
|
||||||
|
|
||||||
f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
|
f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
|
||||||
f.WriteString("hello world")
|
f.WriteString("hello world")
|
||||||
|
|
||||||
content, _ := fileutil.ReadFileToString(path)
|
content, _ := fileutil.ReadFileToString(path)
|
||||||
fmt.Println(content) //hello world
|
fmt.Println(content) //hello world
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ReadFileByLine">ReadFileByLine</span>
|
### <span id="ReadFileByLine">ReadFileByLine</span>
|
||||||
|
|
||||||
<p>Read file line by line, and return slice of lines</p>
|
<p>Read file line by line, and return slice of lines</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -357,6 +398,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ReadFileByLine(path string)([]string, error)
|
func ReadFileByLine(path string)([]string, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -365,25 +407,24 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
path := "./text.txt"
|
path := "./text.txt"
|
||||||
fileutil.CreateFile(path)
|
fileutil.CreateFile(path)
|
||||||
|
|
||||||
f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
|
f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
f.WriteString("hello\nworld")
|
f.WriteString("hello\nworld")
|
||||||
|
|
||||||
contents, _ := fileutil.ReadFileByLine(path)
|
contents, _ := fileutil.ReadFileByLine(path)
|
||||||
fmt.Println(contents) //[]string{"hello", "world"}
|
fmt.Println(contents) //[]string{"hello", "world"}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Zip">Zip</span>
|
### <span id="Zip">Zip</span>
|
||||||
|
|
||||||
<p>Create a zip file of fpath, fpath could be a file or a directory.</p>
|
<p>Create a zip file of fpath, fpath could be a file or a directory.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -391,6 +432,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Zip(fpath string, destPath string) error
|
func Zip(fpath string, destPath string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -398,21 +440,19 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := fileutil.Zip("./test.txt", "./test.zip")
|
err := fileutil.Zip("./test.txt", "./test.zip")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="UnZip">UnZip</span>
|
### <span id="UnZip">UnZip</span>
|
||||||
|
|
||||||
<p>Unzip the file and save it to dest path.</p>
|
<p>Unzip the file and save it to dest path.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -420,6 +460,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func UnZip(zipFile string, destPath string) error
|
func UnZip(zipFile string, destPath string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -427,18 +468,362 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := fileutil.Zip("./test.zip", "./unzip/test.txt")
|
err := fileutil.Zip("./test.zip", "./unzip/test.txt")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="ZipAppendEntry">ZipAppendEntry</span>
|
||||||
|
|
||||||
|
<p>Append a single file or directory by fpath to an existing zip file.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ZipAppendEntry(fpath string, destPath string) error
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := fileutil.ZipAppendEntry("./test.txt", "./test.zip")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="CurrentPath">CurrentPath</span>
|
||||||
|
|
||||||
|
<p>return current absolute path.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func CurrentPath() string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
absPath := CurrentPath()
|
||||||
|
fmt.Println(absPath)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="IsZipFile">IsZipFile</span>
|
||||||
|
|
||||||
|
<p>Checks if file is zip file or not.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func IsZipFile(filepath string) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
isZip := IsZipFile("./zipfile.zip")
|
||||||
|
fmt.Println(isZip)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="FileSize">FileSize</span>
|
||||||
|
|
||||||
|
<p>Returns file size in bytes.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func FileSize(path string) (int64, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
size, err := fileutil.FileSize("./testdata/test.txt")
|
||||||
|
|
||||||
|
fmt.Println(size)
|
||||||
|
fmt.Println(err)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 20
|
||||||
|
// <nil>
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="MTime">MTime</span>
|
||||||
|
|
||||||
|
<p>Returns file modified time(unix timestamp).</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func MTime(filepath string) (int64, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
mtime, err := fileutil.MTime("./testdata/test.txt")
|
||||||
|
|
||||||
|
fmt.Println(mtime)
|
||||||
|
fmt.Println(err)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1682391110
|
||||||
|
// <nil>
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Sha">Sha</span>
|
||||||
|
|
||||||
|
<p>returns file sha value, param `shaType` should be 1, 256 or 512.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Sha(filepath string, shaType ...int) (string, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
sha1, err := fileutil.Sha("./testdata/test.txt", 1)
|
||||||
|
sha256, _ := fileutil.Sha("./testdata/test.txt", 256)
|
||||||
|
sha512, _ := fileutil.Sha("./testdata/test.txt", 512)
|
||||||
|
|
||||||
|
fmt.Println(sha1)
|
||||||
|
fmt.Println(sha256)
|
||||||
|
fmt.Println(sha512)
|
||||||
|
fmt.Println(err)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// dda3cf10c5a6ff6c6659a497bf7261b287af2bc7
|
||||||
|
// aa6d0a3fbc3442c228d606da09e0c1dc98c69a1cac3da1909199e0266171df35
|
||||||
|
// d22aba2a1b7a2e2f512756255cc1c3708905646920cb1eb95e45b531ba74774dbbb89baebf1f716220eb9cf4908f1cfc5b2a01267704d9a59f59d77cab609870
|
||||||
|
// <nil>
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="ReadCsvFile">ReadCsvFile</span>
|
||||||
|
|
||||||
|
<p>Reads file content into slice.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadCsvFile(filepath string) ([][]string, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
content, err := fileutil.ReadCsvFile("./testdata/test.csv")
|
||||||
|
|
||||||
|
fmt.Println(content)
|
||||||
|
fmt.Println(err)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [[Bob 12 male] [Duke 14 male] [Lucy 16 female]]
|
||||||
|
// <nil>
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="WriteCsvFile">WriteCsvFile</span>
|
||||||
|
|
||||||
|
<p>Write content to target csv file.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func WriteCsvFile(filepath string, records [][]string, append bool) error
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
data := [][]string{
|
||||||
|
{"Lili", "22", "female"},
|
||||||
|
{"Jim", "21", "male"},
|
||||||
|
}
|
||||||
|
err := WriteCsvFile("./testdata/test2.csv", data, false)
|
||||||
|
fmt.Println(err)
|
||||||
|
|
||||||
|
content, _ := ReadCsvFile("./testdata/test2.csv")
|
||||||
|
fmt.Println(content)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// <nil>
|
||||||
|
// [[Lili 22 female] [Jim 21 male]]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="WriteBytesToFile">WriteBytesToFile</span>
|
||||||
|
|
||||||
|
<p>Writes bytes to target file.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func WriteBytesToFile(filepath string, content []byte) error
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
filepath := "./bytes.txt"
|
||||||
|
|
||||||
|
file, err := os.Create(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
err = fileutil.WriteBytesToFile(filepath, []byte("hello"))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
content, err := fileutil.ReadFileToString(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
os.Remove(filepath)
|
||||||
|
|
||||||
|
fmt.Println(content)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// hello
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="WriteStringToFile">WriteStringToFile</span>
|
||||||
|
|
||||||
|
<p>Writes string to target file.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func WriteStringToFile(filepath string, content string, append bool) error
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
filepath := "./test.txt"
|
||||||
|
|
||||||
|
file, err := os.Create(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
err = fileutil.WriteStringToFile(filepath, "hello", true)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
content, err := fileutil.ReadFileToString(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
os.Remove(filepath)
|
||||||
|
|
||||||
|
fmt.Println(content)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// hello
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,47 +1,59 @@
|
|||||||
# Fileutil
|
# Fileutil
|
||||||
fileutil包支持文件基本操作。
|
|
||||||
|
fileutil 包支持文件基本操作。
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 源码:
|
## 源码:
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/fileutil/file.go](https://github.com/duke-git/lancet/blob/main/fileutil/file.go)
|
[https://github.com/duke-git/lancet/blob/v1/fileutil/file.go](https://github.com/duke-git/lancet/blob/v1/fileutil/file.go)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 用法:
|
## 用法:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<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)
|
- [ClearFile](#ClearFile)
|
||||||
- [RemoveFile](#RemoveFile)
|
- [CreateFile](#CreateFile)
|
||||||
- [ReadFileToString](#ReadFileToString)
|
- [CreateDir](#CreateDir)
|
||||||
- [ReadFileByLine](#ReadFileByLine)
|
- [CopyFile](#CopyFile)
|
||||||
- [Zip](#Zip)
|
- [FileMode](#FileMode)
|
||||||
- [UnZip](#UnZip)
|
- [MiMeType](#MiMeType)
|
||||||
|
- [IsExist](#IsExist)
|
||||||
|
- [IsLink](#IsLink)
|
||||||
|
- [IsDir](#IsDir)画
|
||||||
|
- [ListFileNames](#ListFileNames)
|
||||||
|
- [RemoveFile](#RemoveFile)
|
||||||
|
- [ReadFileToString](#ReadFileToString)
|
||||||
|
- [ReadFileByLine](#ReadFileByLine)
|
||||||
|
- [Zip](#Zip)
|
||||||
|
- [UnZip](#UnZip)
|
||||||
|
- [ZipAppendEntry](#ZipAppendEntry)
|
||||||
|
- [CurrentPath](#CurrentPath)
|
||||||
|
- [IsZipFile](#IsZipFile)
|
||||||
|
- [FileSize](#FileSize)
|
||||||
|
- [MTime](#MTime)
|
||||||
|
- [Sha](#Sha)
|
||||||
|
- [ReadCsvFile](#ReadCsvFile)
|
||||||
|
- [WriteCsvFile](#WriteCsvFile)
|
||||||
|
- [WriteStringToFile](#WriteStringToFile)
|
||||||
|
- [WriteBytesToFile](#WriteBytesToFile)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 文档
|
## 文档
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ClearFile">ClearFile</span>
|
### <span id="ClearFile">ClearFile</span>
|
||||||
|
|
||||||
<p>清空文件内容</p>
|
<p>清空文件内容</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -49,6 +61,7 @@ import (
|
|||||||
```go
|
```go
|
||||||
func ClearFile(path string) error
|
func ClearFile(path string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -56,7 +69,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -67,14 +80,16 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### <span id="CreateFile">CreateFile</span>
|
### <span id="CreateDir">CreateDir</span>
|
||||||
<p>创建文件,创建成功返回true, 否则返回false</p>
|
|
||||||
|
<p>使用绝对路径创建嵌套目录,例如/a/, /a/b/</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func CreateFile(path string) bool
|
func CreateDir(absPath string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -82,7 +97,33 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := fileutil.CreateDir("/a/")
|
||||||
|
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/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -91,8 +132,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="CopyFile">CopyFile</span>
|
### <span id="CopyFile">CopyFile</span>
|
||||||
|
|
||||||
<p>拷贝文件,会覆盖原有的拷贝文件</p>
|
<p>拷贝文件,会覆盖原有的拷贝文件</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -100,6 +141,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func CopyFile(srcFilePath string, dstFilePath string) error
|
func CopyFile(srcFilePath string, dstFilePath string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -107,20 +149,19 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := fileutil.CopyFile("./test.txt", "./test_copy.txt")
|
err := fileutil.CopyFile("./test.txt", "./test_copy.txt")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="FileMode">FileMode</span>
|
### <span id="FileMode">FileMode</span>
|
||||||
|
|
||||||
<p>获取文件mode信息</p>
|
<p>获取文件mode信息</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -128,6 +169,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func FileMode(path string) (fs.FileMode, error)
|
func FileMode(path string) (fs.FileMode, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -135,28 +177,28 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
mode, err := fileutil.FileMode("./test.txt")
|
mode, err := fileutil.FileMode("./test.txt")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
fmt.Println(mode)
|
fmt.Println(mode)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="MiMeType">MiMeType</span>
|
### <span id="MiMeType">MiMeType</span>
|
||||||
|
|
||||||
<p>获取文件mime类型, 'file'参数的类型必须是string或者*os.File</p>
|
<p>获取文件mime类型, 'file'参数的类型必须是string或者*os.File</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func MiMeType(file any) string
|
func MiMeType(file interface{}) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -165,7 +207,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -178,10 +220,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="IsExist">IsExist</span>
|
### <span id="IsExist">IsExist</span>
|
||||||
|
|
||||||
<p>判断文件或目录是否存在</p>
|
<p>判断文件或目录是否存在</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -189,6 +229,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func IsExist(path string) bool
|
func IsExist(path string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -196,7 +237,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -206,9 +247,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="IsLink">IsLink</span>
|
### <span id="IsLink">IsLink</span>
|
||||||
|
|
||||||
<p>判断文件是否是符号链接</p>
|
<p>判断文件是否是符号链接</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -216,6 +256,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func IsLink(path string) bool
|
func IsLink(path string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -223,7 +264,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -232,16 +273,16 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="IsDir">IsDir</span>
|
### <span id="IsDir">IsDir</span>
|
||||||
|
|
||||||
<p>判断目录是否存在</p>
|
<p>判断目录是否存在</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func IsDir(path string) bool
|
func IsDir(path string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -249,7 +290,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -261,9 +302,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ListFileNames">ListFileNames</span>
|
### <span id="ListFileNames">ListFileNames</span>
|
||||||
|
|
||||||
<p>返回目录下所有文件名</p>
|
<p>返回目录下所有文件名</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -271,6 +311,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ListFileNames(path string) ([]string, error)
|
func ListFileNames(path string) ([]string, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -278,7 +319,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -287,9 +328,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="RemoveFile">RemoveFile</span>
|
### <span id="RemoveFile">RemoveFile</span>
|
||||||
|
|
||||||
<p>删除文件</p>
|
<p>删除文件</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -297,6 +337,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func RemoveFile(path string) error
|
func RemoveFile(path string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -304,19 +345,19 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := fileutil.RemoveFile("./test.txt")
|
err := fileutil.RemoveFile("./test.txt")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="ReadFileToString">ReadFileToString</span>
|
### <span id="ReadFileToString">ReadFileToString</span>
|
||||||
|
|
||||||
<p>读取文件内容并返回字符串</p>
|
<p>读取文件内容并返回字符串</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -324,6 +365,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ReadFileToString(path string) (string, error)
|
func ReadFileToString(path string) (string, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -332,24 +374,23 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
path := "./test.txt"
|
path := "./test.txt"
|
||||||
fileutil.CreateFile(path)
|
fileutil.CreateFile(path)
|
||||||
|
|
||||||
f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
|
f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
|
||||||
f.WriteString("hello world")
|
f.WriteString("hello world")
|
||||||
|
|
||||||
content, _ := fileutil.ReadFileToString(path)
|
content, _ := fileutil.ReadFileToString(path)
|
||||||
fmt.Println(content) //hello world
|
fmt.Println(content) //hello world
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ReadFileByLine">ReadFileByLine</span>
|
### <span id="ReadFileByLine">ReadFileByLine</span>
|
||||||
|
|
||||||
<p>按行读取文件内容,返回字符串切片包含每一行</p>
|
<p>按行读取文件内容,返回字符串切片包含每一行</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -357,6 +398,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func ReadFileByLine(path string)([]string, error)
|
func ReadFileByLine(path string)([]string, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -365,25 +407,24 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
path := "./text.txt"
|
path := "./text.txt"
|
||||||
fileutil.CreateFile(path)
|
fileutil.CreateFile(path)
|
||||||
|
|
||||||
f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
|
f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
f.WriteString("hello\nworld")
|
f.WriteString("hello\nworld")
|
||||||
|
|
||||||
contents, _ := fileutil.ReadFileByLine(path)
|
contents, _ := fileutil.ReadFileByLine(path)
|
||||||
fmt.Println(contents) //[]string{"hello", "world"}
|
fmt.Println(contents) //[]string{"hello", "world"}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Zip">Zip</span>
|
### <span id="Zip">Zip</span>
|
||||||
|
|
||||||
<p>zip压缩文件, fpath参数可以是文件或目录</p>
|
<p>zip压缩文件, fpath参数可以是文件或目录</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -391,6 +432,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Zip(fpath string, destPath string) error
|
func Zip(fpath string, destPath string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -398,28 +440,27 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := fileutil.Zip("./test.txt", "./test.zip")
|
err := fileutil.Zip("./test.txt", "./test.zip")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="UnZip">UnZip</span>
|
### <span id="UnZip">UnZip</span>
|
||||||
|
|
||||||
<p>zip解压缩文件并保存在目录中</p>
|
<p>zip解压缩文件并保存在目录中</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func UnZip(zipFile string, destPath string) error
|
func UnZip(zipFile string, destPath string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -427,18 +468,362 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/fileutil"
|
"github.com/duke-git/lancet/fileutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := fileutil.Zip("./test.zip", "./unzip/test.txt")
|
err := fileutil.Zip("./test.zip", "./unzip/test.txt")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="ZipAppendEntry">ZipAppendEntry</span>
|
||||||
|
|
||||||
|
<p>通过将单个文件或目录追加到现有的zip文件</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ZipAppendEntry(fpath string, destPath string) error
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := fileutil.ZipAppendEntry("./test.txt", "./test.zip")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="CurrentPath">CurrentPath</span>
|
||||||
|
|
||||||
|
<p>返回当前位置的绝对路径。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func CurrentPath() string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
absPath := CurrentPath()
|
||||||
|
fmt.Println(absPath)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="IsZipFile">IsZipFile</span>
|
||||||
|
|
||||||
|
<p>判断文件是否是zip压缩文件。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func IsZipFile(filepath string) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
isZip := IsZipFile("./zipfile.zip")
|
||||||
|
fmt.Println(isZip)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="FileSize">FileSize</span>
|
||||||
|
|
||||||
|
<p>返回文件字节大小。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func FileSize(path string) (int64, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
size, err := fileutil.FileSize("./testdata/test.txt")
|
||||||
|
|
||||||
|
fmt.Println(size)
|
||||||
|
fmt.Println(err)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 20
|
||||||
|
// <nil>
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="MTime">MTime</span>
|
||||||
|
|
||||||
|
<p>返回文件修改时间(unix timestamp).</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func MTime(filepath string) (int64, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
mtime, err := fileutil.MTime("./testdata/test.txt")
|
||||||
|
|
||||||
|
fmt.Println(mtime)
|
||||||
|
fmt.Println(err)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1682391110
|
||||||
|
// <nil>
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Sha">Sha</span>
|
||||||
|
|
||||||
|
<p>返回文件sha值,参数`shaType` 应传值为: 1, 256,512.</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Sha(filepath string, shaType ...int) (string, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
sha1, err := fileutil.Sha("./testdata/test.txt", 1)
|
||||||
|
sha256, _ := fileutil.Sha("./testdata/test.txt", 256)
|
||||||
|
sha512, _ := fileutil.Sha("./testdata/test.txt", 512)
|
||||||
|
|
||||||
|
fmt.Println(sha1)
|
||||||
|
fmt.Println(sha256)
|
||||||
|
fmt.Println(sha512)
|
||||||
|
fmt.Println(err)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// dda3cf10c5a6ff6c6659a497bf7261b287af2bc7
|
||||||
|
// aa6d0a3fbc3442c228d606da09e0c1dc98c69a1cac3da1909199e0266171df35
|
||||||
|
// d22aba2a1b7a2e2f512756255cc1c3708905646920cb1eb95e45b531ba74774dbbb89baebf1f716220eb9cf4908f1cfc5b2a01267704d9a59f59d77cab609870
|
||||||
|
// <nil>
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="ReadCsvFile">ReadCsvFile</span>
|
||||||
|
|
||||||
|
<p>读取csv文件内容到切片</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadCsvFile(filepath string) ([][]string, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
content, err := fileutil.ReadCsvFile("./testdata/test.csv")
|
||||||
|
|
||||||
|
fmt.Println(content)
|
||||||
|
fmt.Println(err)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [[Bob 12 male] [Duke 14 male] [Lucy 16 female]]
|
||||||
|
// <nil>
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="WriteCsvFile">WriteCsvFile</span>
|
||||||
|
|
||||||
|
<p>向csv文件写入内容。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func WriteCsvFile(filepath string, records [][]string, append bool) error
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
data := [][]string{
|
||||||
|
{"Lili", "22", "female"},
|
||||||
|
{"Jim", "21", "male"},
|
||||||
|
}
|
||||||
|
err := WriteCsvFile("./testdata/test2.csv", data, false)
|
||||||
|
fmt.Println(err)
|
||||||
|
|
||||||
|
content, _ := ReadCsvFile("./testdata/test2.csv")
|
||||||
|
fmt.Println(content)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// <nil>
|
||||||
|
// [[Lili 22 female] [Jim 21 male]]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="WriteBytesToFile">WriteBytesToFile</span>
|
||||||
|
|
||||||
|
<p>将bytes写入文件。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func WriteBytesToFile(filepath string, content []byte) error
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
filepath := "./bytes.txt"
|
||||||
|
|
||||||
|
file, err := os.Create(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
err = fileutil.WriteBytesToFile(filepath, []byte("hello"))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
content, err := fileutil.ReadFileToString(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
os.Remove(filepath)
|
||||||
|
|
||||||
|
fmt.Println(content)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// hello
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="WriteStringToFile">WriteStringToFile</span>
|
||||||
|
|
||||||
|
<p>将字符串写入文件。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func WriteStringToFile(filepath string, content string, append bool) error
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
filepath := "./test.txt"
|
||||||
|
|
||||||
|
file, err := os.Create(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
err = fileutil.WriteStringToFile(filepath, "hello", true)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
content, err := fileutil.ReadFileToString(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
os.Remove(filepath)
|
||||||
|
|
||||||
|
fmt.Println(content)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// hello
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,41 +1,50 @@
|
|||||||
# Formatter
|
# Formatter
|
||||||
|
|
||||||
formatter contains some functions for data formatting.
|
formatter contains some functions for data formatting.
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Source:
|
## Source:
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/formatter/formatter.go](https://github.com/duke-git/lancet/blob/main/formatter/formatter.go)
|
[https://github.com/duke-git/lancet/blob/v1/formatter/formatter.go](https://github.com/duke-git/lancet/blob/v1/formatter/formatter.go)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Usage:
|
## Usage:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/v2/formatter"
|
"github.com/duke-git/lancet/formatter"
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Index
|
## Index
|
||||||
- [Comma](#Comma)
|
|
||||||
|
- [Comma](#Comma)
|
||||||
|
- [Pretty](#Pretty)
|
||||||
|
- [PrettyToWriter](#PrettyToWriter)
|
||||||
|
- [DecimalBytes](#DecimalBytes)
|
||||||
|
- [BinaryBytes](#BinaryBytes)
|
||||||
|
- [ParseDecimalBytes](#ParseDecimalBytes)
|
||||||
|
- [ParseBinaryBytes](#ParseBinaryBytes)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Comma">Comma</span>
|
### <span id="Comma">Comma</span>
|
||||||
|
|
||||||
<p>Add comma to number by every 3 numbers from right. ahead by symbol char.
|
<p>Add comma to number by every 3 numbers from right. ahead by symbol char.
|
||||||
Param should be number or numberic string.</p>
|
Param should be number or numberic string.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func Comma(v any, symbol string) string
|
func Comma(value interface{}, symbol string) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -43,7 +52,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/formatter"
|
"github.com/duke-git/lancet/formatter"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -51,3 +60,241 @@ func main() {
|
|||||||
fmt.Println(formatter.Comma(12345.67, "¥")) // "¥12,345.67"
|
fmt.Println(formatter.Comma(12345.67, "¥")) // "¥12,345.67"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="Pretty">Pretty</span>
|
||||||
|
|
||||||
|
<p>Pretty data to JSON string.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Pretty(v interface{}) (string, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/formatter"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1, _ := formatter.Pretty([]string{"a", "b", "c"})
|
||||||
|
result2, _ := formatter.Pretty(map[string]int{"a": 1})
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [
|
||||||
|
// "a",
|
||||||
|
// "b",
|
||||||
|
// "c"
|
||||||
|
// ]
|
||||||
|
// {
|
||||||
|
// "a": 1
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="PrettyToWriter">PrettyToWriter</span>
|
||||||
|
|
||||||
|
<p>Pretty encode data to writer.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func PrettyToWriter(v interface{}, out io.Writer) error
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/formatter"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
type User struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Aage uint `json:"age"`
|
||||||
|
}
|
||||||
|
user := User{Name: "King", Aage: 10000}
|
||||||
|
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
err := formatter.PrettyToWriter(user, buf)
|
||||||
|
|
||||||
|
fmt.Println(buf)
|
||||||
|
fmt.Println(err)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// {
|
||||||
|
// "name": "King",
|
||||||
|
// "age": 10000
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// <nil>
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="DecimalBytes">DecimalBytes</span>
|
||||||
|
|
||||||
|
<p>Returns a human readable byte size under decimal standard (base 1000). The precision parameter specifies the number of digits after the decimal point, which is 4 for default.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func DecimalBytes(size float64, precision ...int) string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/formatter"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := formatter.DecimalBytes(1000)
|
||||||
|
result2 := formatter.DecimalBytes(1024)
|
||||||
|
result3 := formatter.DecimalBytes(1234567)
|
||||||
|
result4 := formatter.DecimalBytes(1234567, 3)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1KB
|
||||||
|
// 1.024KB
|
||||||
|
// 1.2346MB
|
||||||
|
// 1.235MB
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="BinaryBytes">BinaryBytes</span>
|
||||||
|
|
||||||
|
<p>Returns a human readable byte size under binary standard (base 1024). The precision parameter specifies the number of digits after the decimal point, which is 4 for default.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func BinaryBytes(size float64, precision ...int) string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/formatter"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := formatter.BinaryBytes(1024)
|
||||||
|
result2 := formatter.BinaryBytes(1024 * 1024)
|
||||||
|
result3 := formatter.BinaryBytes(1234567)
|
||||||
|
result4 := formatter.BinaryBytes(1234567, 2)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1KiB
|
||||||
|
// 1MiB
|
||||||
|
// 1.1774MiB
|
||||||
|
// 1.18MiB
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="ParseDecimalBytes">ParseDecimalBytes</span>
|
||||||
|
|
||||||
|
<p>Returns the human readable bytes size string into the amount it represents(base 1000).</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ParseDecimalBytes(size string) (uint64, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/formatter"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1, _ := formatter.ParseDecimalBytes("12")
|
||||||
|
result2, _ := formatter.ParseDecimalBytes("12k")
|
||||||
|
result3, _ := formatter.ParseDecimalBytes("12 Kb")
|
||||||
|
result4, _ := formatter.ParseDecimalBytes("12.2 kb")
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 12
|
||||||
|
// 12000
|
||||||
|
// 12000
|
||||||
|
// 12200
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="ParseBinaryBytes">ParseBinaryBytes</span>
|
||||||
|
|
||||||
|
<p>Returns the human readable bytes size string into the amount it represents(base 1024).</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ParseBinaryBytes(size string) (uint64, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/formatter"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1, _ := formatter.ParseBinaryBytes("12")
|
||||||
|
result2, _ := formatter.ParseBinaryBytes("12ki")
|
||||||
|
result3, _ := formatter.ParseBinaryBytes("12 KiB")
|
||||||
|
result4, _ := formatter.ParseBinaryBytes("12.2 kib")
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 12
|
||||||
|
// 12288
|
||||||
|
// 12288
|
||||||
|
// 12492
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,40 +1,49 @@
|
|||||||
# Formatter
|
# Formatter
|
||||||
formatter格式化器包含一些数据格式化处理方法。
|
|
||||||
|
formatter 格式化器包含一些数据格式化处理方法。
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 源码:
|
## 源码:
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/formatter/formatter.go](https://github.com/duke-git/lancet/blob/main/formatter/formatter.go)
|
[https://github.com/duke-git/lancet/blob/v1/formatter/formatter.go](https://github.com/duke-git/lancet/blob/v1/formatter/formatter.go)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 用法:
|
## 用法:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/v2/formatter"
|
"github.com/duke-git/lancet/formatter"
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 目录
|
## 目录
|
||||||
- [Comma](#Comma)
|
|
||||||
|
- [Comma](#Comma)
|
||||||
|
- [Pretty](#Pretty)
|
||||||
|
- [PrettyToWriter](#PrettyToWriter)
|
||||||
|
- [DecimalBytes](#DecimalBytes)
|
||||||
|
- [BinaryBytes](#BinaryBytes)
|
||||||
|
- [ParseDecimalBytes](#ParseDecimalBytes)
|
||||||
|
- [ParseBinaryBytes](#ParseBinaryBytes)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 文档
|
## 文档
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Comma">Comma</span>
|
### <span id="Comma">Comma</span>
|
||||||
|
|
||||||
<p>用逗号每隔3位分割数字/字符串,签名添加符号。参数必须是数字或者可以转为数字的字符串</p>
|
<p>用逗号每隔3位分割数字/字符串,签名添加符号。参数必须是数字或者可以转为数字的字符串</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func Comma(v any, symbol string) string
|
func Comma(v interface{}, symbol string) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -42,7 +51,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/formatter"
|
"github.com/duke-git/lancet/formatter"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -50,3 +59,241 @@ func main() {
|
|||||||
fmt.Println(formatter.Comma(12345.67, "¥")) // "¥12,345.67"
|
fmt.Println(formatter.Comma(12345.67, "¥")) // "¥12,345.67"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="Pretty">Pretty</span>
|
||||||
|
|
||||||
|
<p>返回pretty JSON字符串.</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Pretty(v interface{}) (string, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/formatter"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1, _ := formatter.Pretty([]string{"a", "b", "c"})
|
||||||
|
result2, _ := formatter.Pretty(map[string]int{"a": 1})
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [
|
||||||
|
// "a",
|
||||||
|
// "b",
|
||||||
|
// "c"
|
||||||
|
// ]
|
||||||
|
// {
|
||||||
|
// "a": 1
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="PrettyToWriter">PrettyToWriter</span>
|
||||||
|
|
||||||
|
<p>Pretty encode数据到writer。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func PrettyToWriter(v interface{}, out io.Writer) error
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/formatter"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
type User struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Aage uint `json:"age"`
|
||||||
|
}
|
||||||
|
user := User{Name: "King", Aage: 10000}
|
||||||
|
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
err := formatter.PrettyToWriter(user, buf)
|
||||||
|
|
||||||
|
fmt.Println(buf)
|
||||||
|
fmt.Println(err)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// {
|
||||||
|
// "name": "King",
|
||||||
|
// "age": 10000
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// <nil>
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="DecimalBytes">DecimalBytes</span>
|
||||||
|
|
||||||
|
<p>返回十进制标准(以1000为基数)下的可读字节单位字符串。precision参数指定小数点后的位数,默认为4。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func DecimalBytes(size float64, precision ...int) string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/formatter"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := formatter.DecimalBytes(1000)
|
||||||
|
result2 := formatter.DecimalBytes(1024)
|
||||||
|
result3 := formatter.DecimalBytes(1234567)
|
||||||
|
result4 := formatter.DecimalBytes(1234567, 3)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1KB
|
||||||
|
// 1.024KB
|
||||||
|
// 1.2346MB
|
||||||
|
// 1.235MB
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="BinaryBytes">BinaryBytes</span>
|
||||||
|
|
||||||
|
<p>返回binary标准(以1024为基数)下的可读字节单位字符串。precision参数指定小数点后的位数,默认为4。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func BinaryBytes(size float64, precision ...int) string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/formatter"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := formatter.BinaryBytes(1024)
|
||||||
|
result2 := formatter.BinaryBytes(1024 * 1024)
|
||||||
|
result3 := formatter.BinaryBytes(1234567)
|
||||||
|
result4 := formatter.BinaryBytes(1234567, 2)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1KiB
|
||||||
|
// 1MiB
|
||||||
|
// 1.1774MiB
|
||||||
|
// 1.18MiB
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="ParseDecimalBytes">ParseDecimalBytes</span>
|
||||||
|
|
||||||
|
<p>将字节单位字符串转换成其所表示的字节数(以1000为基数)。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ParseDecimalBytes(size string) (uint64, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/formatter"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1, _ := formatter.ParseDecimalBytes("12")
|
||||||
|
result2, _ := formatter.ParseDecimalBytes("12k")
|
||||||
|
result3, _ := formatter.ParseDecimalBytes("12 Kb")
|
||||||
|
result4, _ := formatter.ParseDecimalBytes("12.2 kb")
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 12
|
||||||
|
// 12000
|
||||||
|
// 12000
|
||||||
|
// 12200
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="ParseBinaryBytes">ParseBinaryBytes</span>
|
||||||
|
|
||||||
|
<p>将字节单位字符串转换成其所表示的字节数(以1024为基数)。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ParseBinaryBytes(size string) (uint64, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/formatter"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1, _ := formatter.ParseBinaryBytes("12")
|
||||||
|
result2, _ := formatter.ParseBinaryBytes("12ki")
|
||||||
|
result3, _ := formatter.ParseBinaryBytes("12 KiB")
|
||||||
|
result4, _ := formatter.ParseBinaryBytes("12.2 kib")
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 12
|
||||||
|
// 12288
|
||||||
|
// 12288
|
||||||
|
// 12492
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
296
docs/function.md
296
docs/function.md
@@ -1,47 +1,52 @@
|
|||||||
# Function
|
# Function
|
||||||
|
|
||||||
Package function can control the flow of function execution and support part of functional programming.
|
Package function can control the flow of function execution and support part of functional programming.
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Source:
|
## 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/v1/function/function.go](https://github.com/duke-git/lancet/blob/v1/function/function.go)
|
||||||
- [https://github.com/duke-git/lancet/blob/main/function/watcher.go](https://github.com/duke-git/lancet/blob/main/function/watcher.go)
|
[https://github.com/duke-git/lancet/blob/v1/function/watcher.go](https://github.com/duke-git/lancet/blob/v1/function/watcher.go)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Usage:
|
## Usage:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/v2/function"
|
"github.com/duke-git/lancet/function"
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Index
|
## Index
|
||||||
- [After](#After)
|
|
||||||
- [Before](#Before)
|
- [After](#After)
|
||||||
- [Curry](#Curry)
|
- [Before](#Before)
|
||||||
- [Compose](#Compose)
|
- [Curry](#Curry)
|
||||||
- [Debounced](#Debounced)
|
- [Compose](#Compose)
|
||||||
- [Delay](#Delay)
|
- [Debounced](#Debounced)
|
||||||
- [Watcher](#Watcher)
|
- [Delay](#Delay)
|
||||||
|
- [Pipeline](#Pipeline)
|
||||||
|
- [Schedule](#Schedule)
|
||||||
|
- [Watcher](#Watcher)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="After">After</span>
|
### <span id="After">After</span>
|
||||||
|
|
||||||
<p>Creates a function that invokes given func once it's called n or more times.</p>
|
<p>Creates a function that invokes given func once it's called n or more times.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func After(n int, fn any) func(args ...any) []reflect.Value
|
func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -49,37 +54,35 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/function"
|
"github.com/duke-git/lancet/function"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
arr := []string{"a", "b"}
|
arr := []string{"a", "b"}
|
||||||
f := function.After(len(arr), func(i int) int {
|
f := function.After(len(arr), func(i int) int {
|
||||||
fmt.Println("last print")
|
fmt.Println("last print")
|
||||||
return i
|
return i
|
||||||
})
|
})
|
||||||
|
|
||||||
type cb func(args ...any) []reflect.Value
|
type cb func(args ...interface{}) []reflect.Value
|
||||||
print := func(i int, s string, fn cb) {
|
print := func(i int, s string, fn cb) {
|
||||||
fmt.Printf("arr[%d] is %s \n", i, s)
|
fmt.Printf("arr[%d] is %s \n", i, s)
|
||||||
fn(i)
|
fn(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("arr is", arr)
|
fmt.Println("arr is", arr)
|
||||||
for i := 0; i < len(arr); i++ {
|
for i := 0; i < len(arr); i++ {
|
||||||
print(i, arr[i], f)
|
print(i, arr[i], f)
|
||||||
}
|
}
|
||||||
|
|
||||||
//output:
|
//output:
|
||||||
// arr is [a b]
|
// arr is [a b]
|
||||||
// arr[0] is a
|
// arr[0] is a
|
||||||
// arr[1] is b
|
// arr[1] is b
|
||||||
// last print
|
// last print
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Before">Before</span>
|
### <span id="Before">Before</span>
|
||||||
|
|
||||||
<p>creates a function that invokes func once it's called less than n times.</p>
|
<p>creates a function that invokes func once it's called less than n times.</p>
|
||||||
@@ -87,8 +90,9 @@ func main() {
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func Before(n int, fn any) func(args ...any) []reflect.Value
|
func Before(n int, fn interface{}) func(args ...interface{}) []reflect.Value
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -96,36 +100,34 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/function"
|
"github.com/duke-git/lancet/function"
|
||||||
"github.com/duke-git/lancet/v2/internal"
|
"github.com/duke-git/lancet/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
assert := internal.NewAssert(t, "TestBefore")
|
assert := internal.NewAssert(t, "TestBefore")
|
||||||
|
|
||||||
arr := []string{"a", "b", "c", "d", "e"}
|
arr := []string{"a", "b", "c", "d", "e"}
|
||||||
f := function.Before(3, func(i int) int {
|
f := function.Before(3, func(i int) int {
|
||||||
return i
|
return i
|
||||||
})
|
})
|
||||||
|
|
||||||
var res []int64
|
var res []int64
|
||||||
type cb func(args ...any) []reflect.Value
|
type cb func(args ...interface{}) []reflect.Value
|
||||||
appendStr := func(i int, s string, fn cb) {
|
appendStr := func(i int, s string, fn cb) {
|
||||||
v := fn(i)
|
v := fn(i)
|
||||||
res = append(res, v[0].Int())
|
res = append(res, v[0].Int())
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(arr); i++ {
|
for i := 0; i < len(arr); i++ {
|
||||||
appendStr(i, arr[i], f)
|
appendStr(i, arr[i], f)
|
||||||
}
|
}
|
||||||
|
|
||||||
expected := []int64{0, 1, 2, 2, 2}
|
expected := []int64{0, 1, 2, 2, 2}
|
||||||
assert.Equal(expected, res)
|
assert.Equal(expected, res)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Curry">Curry</span>
|
### <span id="Curry">Curry</span>
|
||||||
|
|
||||||
<p>Make a curry function.</p>
|
<p>Make a curry function.</p>
|
||||||
@@ -133,9 +135,10 @@ func main() {
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type Fn func(...any) any
|
type Fn func(...interface{}) interface{}
|
||||||
func (f Fn) Curry(i any) func(...any) any
|
func (f Fn) Curry(i interface{}) func(...interface{}) interface{}
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -143,24 +146,22 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/function"
|
"github.com/duke-git/lancet/function"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
add := func(a, b int) int {
|
add := func(a, b int) int {
|
||||||
return a + b
|
return a + b
|
||||||
}
|
}
|
||||||
var addCurry function.Fn = func(values ...any) any {
|
var addCurry function.Fn = func(values ...interface{}) interface{} {
|
||||||
return add(values[0].(int), values[1].(int))
|
return add(values[0].(int), values[1].(int))
|
||||||
}
|
}
|
||||||
add1 := addCurry.Curry(1)
|
add1 := addCurry.Curry(1)
|
||||||
result := add1(2)
|
result := add1(2)
|
||||||
fmt.Println(result) //3
|
fmt.Println(result) //3
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Compose">Compose</span>
|
### <span id="Compose">Compose</span>
|
||||||
|
|
||||||
<p>Compose the function list from right to left, then return the composed function.</p>
|
<p>Compose the function list from right to left, then return the composed function.</p>
|
||||||
@@ -168,8 +169,9 @@ func main() {
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func Compose(fnList ...func(...any) any) func(...any) any
|
func Compose(fnList ...func(...interface{}) interface{}) func(...interface{}) interface{}
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -177,26 +179,24 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/function"
|
"github.com/duke-git/lancet/function"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
add1 := func(v ...any) any {
|
add1 := func(v ...interface{}) interface{} {
|
||||||
return v[0].(int) + 1
|
return v[0].(int) + 1
|
||||||
}
|
}
|
||||||
add2 := func(v ...any) any {
|
add2 := func(v ...interface{}) interface{} {
|
||||||
return v[0].(int) + 2
|
return v[0].(int) + 2
|
||||||
}
|
}
|
||||||
|
|
||||||
add3 := function.Compose(add1, add2)
|
add3 := function.Compose(add1, add2)
|
||||||
result := add3(1)
|
result := add3(1)
|
||||||
|
|
||||||
fmt.Println(result) //4
|
fmt.Println(result) //4
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Debounced">Debounced</span>
|
### <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>
|
<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>
|
||||||
@@ -206,6 +206,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Debounced(fn func(), duration time.Duration) func()
|
func Debounced(fn func(), duration time.Duration) func()
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -213,32 +214,30 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/function"
|
"github.com/duke-git/lancet/function"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
count := 0
|
count := 0
|
||||||
add := func() {
|
add := func() {
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
|
|
||||||
debouncedAdd := function.Debounced(add, 50*time.Microsecond)
|
debouncedAdd := function.Debounced(add, 50*time.Microsecond)
|
||||||
function.debouncedAdd()
|
function.debouncedAdd()
|
||||||
function.debouncedAdd()
|
function.debouncedAdd()
|
||||||
function.debouncedAdd()
|
function.debouncedAdd()
|
||||||
function.debouncedAdd()
|
function.debouncedAdd()
|
||||||
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
fmt.Println(count) //1
|
fmt.Println(count) //1
|
||||||
|
|
||||||
function.debouncedAdd()
|
function.debouncedAdd()
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
fmt.Println(count) //2
|
fmt.Println(count) //2
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Delay">Delay</span>
|
### <span id="Delay">Delay</span>
|
||||||
|
|
||||||
<p>Invoke function after delayed time.</p>
|
<p>Invoke function after delayed time.</p>
|
||||||
@@ -246,8 +245,9 @@ func main() {
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func Delay(delay time.Duration, fn any, args ...any)
|
func Delay(delay time.Duration, fn interface{}, args ...interface{})
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -255,19 +255,17 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/function"
|
"github.com/duke-git/lancet/function"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var print = func(s string) {
|
var print = func(s string) {
|
||||||
fmt.Println(count) //test delay
|
fmt.Println(count) //test delay
|
||||||
}
|
}
|
||||||
function.Delay(2*time.Second, print, "test delay")
|
function.Delay(2*time.Second, print, "test delay")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Schedule">Schedule</span>
|
### <span id="Schedule">Schedule</span>
|
||||||
|
|
||||||
<p>Invoke function every duration time, until close the returned bool chan.</p>
|
<p>Invoke function every duration time, until close the returned bool chan.</p>
|
||||||
@@ -275,8 +273,9 @@ func main() {
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func Schedule(d time.Duration, fn any, args ...any) chan bool
|
func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -284,24 +283,65 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/function"
|
"github.com/duke-git/lancet/function"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var res []string
|
var res []string
|
||||||
appendStr := func(s string) {
|
appendStr := func(s string) {
|
||||||
res = append(res, s)
|
res = append(res, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
stop := function.Schedule(1*time.Second, appendStr, "*")
|
stop := function.Schedule(1*time.Second, appendStr, "*")
|
||||||
time.Sleep(5 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
close(stop)
|
close(stop)
|
||||||
|
|
||||||
fmt.Println(res) //[* * * * *]
|
fmt.Println(res) //[* * * * *]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="Pipeline">Pipeline</span>
|
||||||
|
|
||||||
|
<p>Pipeline takes a list of functions and returns a function whose param will be passed into
|
||||||
|
the functions one by one.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Pipeline(funcs ...func(interface{}) interface{}) func(interface{}) interface{}
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/function"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
addOne := func(x interface{}) interface{} {
|
||||||
|
return x.(int) + 1
|
||||||
|
}
|
||||||
|
double := func(x interface{}) interface{} {
|
||||||
|
return 2 * x.(int)
|
||||||
|
}
|
||||||
|
square := func(x interface{}) interface{} {
|
||||||
|
return x.(int) * x.(int)
|
||||||
|
}
|
||||||
|
|
||||||
|
f := function.Pipeline(addOne, double, square)
|
||||||
|
|
||||||
|
result := fn(2)
|
||||||
|
|
||||||
|
fmt.Println(result)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 36
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="Watcher">Watcher</span>
|
### <span id="Watcher">Watcher</span>
|
||||||
|
|
||||||
@@ -311,15 +351,16 @@ func main() {
|
|||||||
|
|
||||||
```go
|
```go
|
||||||
type Watcher struct {
|
type Watcher struct {
|
||||||
startTime int64
|
startTime int64
|
||||||
stopTime int64
|
stopTime int64
|
||||||
excuting bool
|
excuting bool
|
||||||
}
|
}
|
||||||
func (w *Watcher) Start() //start the watcher
|
func (w *Watcher) Start() //start the watcher
|
||||||
func (w *Watcher) Stop() //stop the watcher
|
func (w *Watcher) Stop() //stop the watcher
|
||||||
func (w *Watcher) Reset() //reset the watcher
|
func (w *Watcher) Reset() //reset the watcher
|
||||||
func (w *Watcher) GetElapsedTime() time.Duration //get the elapsed time of function execution
|
func (w *Watcher) GetElapsedTime() time.Duration //get the elapsed time of function execution
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -327,38 +368,35 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/function"
|
"github.com/duke-git/lancet/function"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
w := &function.Watcher{}
|
w := &function.Watcher{}
|
||||||
w.Start()
|
w.Start()
|
||||||
|
|
||||||
longRunningTask()
|
longRunningTask()
|
||||||
|
|
||||||
fmt.Println(w.excuting) //true
|
fmt.Println(w.excuting) //true
|
||||||
|
|
||||||
w.Stop()
|
w.Stop()
|
||||||
|
|
||||||
eapsedTime := w.GetElapsedTime().Milliseconds()
|
eapsedTime := w.GetElapsedTime().Milliseconds()
|
||||||
fmt.Println(eapsedTime)
|
fmt.Println(eapsedTime)
|
||||||
|
|
||||||
w.Reset()
|
w.Reset()
|
||||||
|
|
||||||
fmt.Println(w.excuting) //false
|
fmt.Println(w.excuting) //false
|
||||||
|
|
||||||
fmt.Println(w.startTime) //0
|
fmt.Println(w.startTime) //0
|
||||||
fmt.Println(w.stopTime) //0
|
fmt.Println(w.stopTime) //0
|
||||||
}
|
}
|
||||||
|
|
||||||
func longRunningTask() {
|
func longRunningTask() {
|
||||||
var slice []int64
|
var slice []int64
|
||||||
for i := 0; i < 10000000; i++ {
|
for i := 0; i < 10000000; i++ {
|
||||||
slice = append(slice, int64(i))
|
slice = append(slice, int64(i))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,47 +1,52 @@
|
|||||||
# Function
|
# Function
|
||||||
function函数包控制函数执行流程,包含部分函数式编程。
|
|
||||||
|
function 函数包控制函数执行流程,包含部分函数式编程。
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<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/v1/function/function.go](https://github.com/duke-git/lancet/blob/v1/function/function.go)
|
||||||
- [https://github.com/duke-git/lancet/blob/main/function/watcher.go](https://github.com/duke-git/lancet/blob/main/function/watcher.go)
|
[https://github.com/duke-git/lancet/blob/v1/function/watcher.go](https://github.com/duke-git/lancet/blob/v1/function/watcher.go)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 用法:
|
## 用法:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/v2/function"
|
"github.com/duke-git/lancet/function"
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 目录
|
## 目录
|
||||||
- [After](#After)
|
|
||||||
- [Before](#Before)
|
- [After](#After)
|
||||||
- [Curry](#Curry)
|
- [Before](#Before)
|
||||||
- [Compose](#Compose)
|
- [Curry](#Curry)
|
||||||
- [Debounced](#Debounced)
|
- [Compose](#Compose)
|
||||||
- [Delay](#Delay)
|
- [Debounced](#Debounced)
|
||||||
- [Watcher](#Watcher)
|
- [Delay](#Delay)
|
||||||
|
- [Pipeline](#Pipeline)
|
||||||
|
- [Schedule](#Schedule)
|
||||||
|
- [Watcher](#Watcher)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 文档
|
## 文档
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="After">After</span>
|
### <span id="After">After</span>
|
||||||
|
|
||||||
<p>创建一个函数,当他被调用n或更多次之后将马上触发fn</p>
|
<p>创建一个函数,当他被调用n或更多次之后将马上触发fn</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func After(n int, fn any) func(args ...any) []reflect.Value
|
func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -49,37 +54,35 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/function"
|
"github.com/duke-git/lancet/function"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
arr := []string{"a", "b"}
|
arr := []string{"a", "b"}
|
||||||
f := function.After(len(arr), func(i int) int {
|
f := function.After(len(arr), func(i int) int {
|
||||||
fmt.Println("last print")
|
fmt.Println("last print")
|
||||||
return i
|
return i
|
||||||
})
|
})
|
||||||
|
|
||||||
type cb func(args ...any) []reflect.Value
|
type cb func(args ...interface{}) []reflect.Value
|
||||||
print := func(i int, s string, fn cb) {
|
print := func(i int, s string, fn cb) {
|
||||||
fmt.Printf("arr[%d] is %s \n", i, s)
|
fmt.Printf("arr[%d] is %s \n", i, s)
|
||||||
fn(i)
|
fn(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("arr is", arr)
|
fmt.Println("arr is", arr)
|
||||||
for i := 0; i < len(arr); i++ {
|
for i := 0; i < len(arr); i++ {
|
||||||
print(i, arr[i], f)
|
print(i, arr[i], f)
|
||||||
}
|
}
|
||||||
|
|
||||||
//output:
|
//output:
|
||||||
// arr is [a b]
|
// arr is [a b]
|
||||||
// arr[0] is a
|
// arr[0] is a
|
||||||
// arr[1] is b
|
// arr[1] is b
|
||||||
// last print
|
// last print
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Before">Before</span>
|
### <span id="Before">Before</span>
|
||||||
|
|
||||||
<p>创建一个函数,调用次数不超过n次,之后再调用这个函数,将返回一次最后调用fn的结果</p>
|
<p>创建一个函数,调用次数不超过n次,之后再调用这个函数,将返回一次最后调用fn的结果</p>
|
||||||
@@ -87,8 +90,9 @@ func main() {
|
|||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func Before(n int, fn any) func(args ...any) []reflect.Value
|
func Before(n int, fn interface{}) func(args ...interface{}) []reflect.Value
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -96,36 +100,34 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/function"
|
"github.com/duke-git/lancet/function"
|
||||||
"github.com/duke-git/lancet/v2/internal"
|
"github.com/duke-git/lancet/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
assert := internal.NewAssert(t, "TestBefore")
|
assert := internal.NewAssert(t, "TestBefore")
|
||||||
|
|
||||||
arr := []string{"a", "b", "c", "d", "e"}
|
arr := []string{"a", "b", "c", "d", "e"}
|
||||||
f := function.Before(3, func(i int) int {
|
f := function.Before(3, func(i int) int {
|
||||||
return i
|
return i
|
||||||
})
|
})
|
||||||
|
|
||||||
var res []int64
|
var res []int64
|
||||||
type cb func(args ...any) []reflect.Value
|
type cb func(args ...interface{}) []reflect.Value
|
||||||
appendStr := func(i int, s string, fn cb) {
|
appendStr := func(i int, s string, fn cb) {
|
||||||
v := fn(i)
|
v := fn(i)
|
||||||
res = append(res, v[0].Int())
|
res = append(res, v[0].Int())
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(arr); i++ {
|
for i := 0; i < len(arr); i++ {
|
||||||
appendStr(i, arr[i], f)
|
appendStr(i, arr[i], f)
|
||||||
}
|
}
|
||||||
|
|
||||||
expected := []int64{0, 1, 2, 2, 2}
|
expected := []int64{0, 1, 2, 2, 2}
|
||||||
assert.Equal(expected, res)
|
assert.Equal(expected, res)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Curry">Curry</span>
|
### <span id="Curry">Curry</span>
|
||||||
|
|
||||||
<p>创建一个柯里化的函数</p>
|
<p>创建一个柯里化的函数</p>
|
||||||
@@ -133,9 +135,10 @@ func main() {
|
|||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type Fn func(...any) any
|
type Fn func(...interface{}) interface{}
|
||||||
func (f Fn) Curry(i any) func(...any) any
|
func (f Fn) Curry(i interface{}) func(...interface{}) interface{}
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -143,24 +146,22 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/function"
|
"github.com/duke-git/lancet/function"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
add := func(a, b int) int {
|
add := func(a, b int) int {
|
||||||
return a + b
|
return a + b
|
||||||
}
|
}
|
||||||
var addCurry function.Fn = func(values ...any) any {
|
var addCurry function.Fn = func(values ...interface{}) interface{} {
|
||||||
return add(values[0].(int), values[1].(int))
|
return add(values[0].(int), values[1].(int))
|
||||||
}
|
}
|
||||||
add1 := addCurry.Curry(1)
|
add1 := addCurry.Curry(1)
|
||||||
result := add1(2)
|
result := add1(2)
|
||||||
fmt.Println(result) //3
|
fmt.Println(result) //3
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Compose">Compose</span>
|
### <span id="Compose">Compose</span>
|
||||||
|
|
||||||
<p>从右至左组合函数列表fnList, 返回组合后的函数</p>
|
<p>从右至左组合函数列表fnList, 返回组合后的函数</p>
|
||||||
@@ -168,8 +169,9 @@ func main() {
|
|||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func Compose(fnList ...func(...any) any) func(...any) any
|
func Compose(fnList ...func(...interface{}) interface{}) func(...interface{}) interface{}
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -177,26 +179,24 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/function"
|
"github.com/duke-git/lancet/function"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
add1 := func(v ...any) any {
|
add1 := func(v ...interface{}) interface{} {
|
||||||
return v[0].(int) + 1
|
return v[0].(int) + 1
|
||||||
}
|
}
|
||||||
add2 := func(v ...any) any {
|
add2 := func(v ...interface{}) interface{} {
|
||||||
return v[0].(int) + 2
|
return v[0].(int) + 2
|
||||||
}
|
}
|
||||||
|
|
||||||
add3 := function.Compose(add1, add2)
|
add3 := function.Compose(add1, add2)
|
||||||
result := add3(1)
|
result := add3(1)
|
||||||
|
|
||||||
fmt.Println(result) //4
|
fmt.Println(result) //4
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Debounced">Debounced</span>
|
### <span id="Debounced">Debounced</span>
|
||||||
|
|
||||||
<p>创建一个 debounced 函数,该函数延迟调用 fn 直到自上次调用 debounced 函数后等待持续时间过去。</p>
|
<p>创建一个 debounced 函数,该函数延迟调用 fn 直到自上次调用 debounced 函数后等待持续时间过去。</p>
|
||||||
@@ -206,6 +206,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Debounced(fn func(), duration time.Duration) func()
|
func Debounced(fn func(), duration time.Duration) func()
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -213,32 +214,30 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/function"
|
"github.com/duke-git/lancet/function"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
count := 0
|
count := 0
|
||||||
add := func() {
|
add := func() {
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
|
|
||||||
debouncedAdd := function.Debounced(add, 50*time.Microsecond)
|
debouncedAdd := function.Debounced(add, 50*time.Microsecond)
|
||||||
function.debouncedAdd()
|
function.debouncedAdd()
|
||||||
function.debouncedAdd()
|
function.debouncedAdd()
|
||||||
function.debouncedAdd()
|
function.debouncedAdd()
|
||||||
function.debouncedAdd()
|
function.debouncedAdd()
|
||||||
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
fmt.Println(count) //1
|
fmt.Println(count) //1
|
||||||
|
|
||||||
function.debouncedAdd()
|
function.debouncedAdd()
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
fmt.Println(count) //2
|
fmt.Println(count) //2
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Delay">Delay</span>
|
### <span id="Delay">Delay</span>
|
||||||
|
|
||||||
<p>延迟delay时间后调用函数</p>
|
<p>延迟delay时间后调用函数</p>
|
||||||
@@ -246,8 +245,9 @@ func main() {
|
|||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func Delay(delay time.Duration, fn any, args ...any)
|
func Delay(delay time.Duration, fn interface{}, args ...interface{})
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -255,19 +255,17 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/function"
|
"github.com/duke-git/lancet/function"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var print = func(s string) {
|
var print = func(s string) {
|
||||||
fmt.Println(count) //test delay
|
fmt.Println(count) //test delay
|
||||||
}
|
}
|
||||||
function.Delay(2*time.Second, print, "test delay")
|
function.Delay(2*time.Second, print, "test delay")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Schedule">Schedule</span>
|
### <span id="Schedule">Schedule</span>
|
||||||
|
|
||||||
<p>每次持续时间调用函数,直到关闭返回的 bool chan</p>
|
<p>每次持续时间调用函数,直到关闭返回的 bool chan</p>
|
||||||
@@ -275,8 +273,9 @@ func main() {
|
|||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func Schedule(d time.Duration, fn any, args ...any) chan bool
|
func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -284,24 +283,64 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/function"
|
"github.com/duke-git/lancet/function"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var res []string
|
var res []string
|
||||||
appendStr := func(s string) {
|
appendStr := func(s string) {
|
||||||
res = append(res, s)
|
res = append(res, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
stop := function.Schedule(1*time.Second, appendStr, "*")
|
stop := function.Schedule(1*time.Second, appendStr, "*")
|
||||||
time.Sleep(5 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
close(stop)
|
close(stop)
|
||||||
|
|
||||||
fmt.Println(res) //[* * * * *]
|
fmt.Println(res) //[* * * * *]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="Pipeline">Pipeline</span>
|
||||||
|
|
||||||
|
<p>管道执行多个函数</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Pipeline(funcs ...func(interface{}) interface{}) func(interface{}) interface{}
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/function"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
addOne := func(x interface{}) interface{} {
|
||||||
|
return x.(int) + 1
|
||||||
|
}
|
||||||
|
double := func(x interface{}) interface{} {
|
||||||
|
return 2 * x.(int)
|
||||||
|
}
|
||||||
|
square := func(x interface{}) interface{} {
|
||||||
|
return x.(int) * x.(int)
|
||||||
|
}
|
||||||
|
|
||||||
|
f := function.Pipeline(addOne, double, square)
|
||||||
|
|
||||||
|
result := fn(2)
|
||||||
|
|
||||||
|
fmt.Println(result)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 36
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="Watcher">Watcher</span>
|
### <span id="Watcher">Watcher</span>
|
||||||
|
|
||||||
@@ -311,15 +350,16 @@ func main() {
|
|||||||
|
|
||||||
```go
|
```go
|
||||||
type Watcher struct {
|
type Watcher struct {
|
||||||
startTime int64
|
startTime int64
|
||||||
stopTime int64
|
stopTime int64
|
||||||
excuting bool
|
excuting bool
|
||||||
}
|
}
|
||||||
func (w *Watcher) Start() //start the watcher
|
func (w *Watcher) Start() //start the watcher
|
||||||
func (w *Watcher) Stop() //stop the watcher
|
func (w *Watcher) Stop() //stop the watcher
|
||||||
func (w *Watcher) Reset() //reset the watcher
|
func (w *Watcher) Reset() //reset the watcher
|
||||||
func (w *Watcher) GetElapsedTime() time.Duration //get the elapsed time of function execution
|
func (w *Watcher) GetElapsedTime() time.Duration //get the elapsed time of function execution
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -327,38 +367,35 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/function"
|
"github.com/duke-git/lancet/function"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
w := &function.Watcher{}
|
w := &function.Watcher{}
|
||||||
w.Start()
|
w.Start()
|
||||||
|
|
||||||
longRunningTask()
|
longRunningTask()
|
||||||
|
|
||||||
fmt.Println(w.excuting) //true
|
fmt.Println(w.excuting) //true
|
||||||
|
|
||||||
w.Stop()
|
w.Stop()
|
||||||
|
|
||||||
eapsedTime := w.GetElapsedTime().Milliseconds()
|
eapsedTime := w.GetElapsedTime().Milliseconds()
|
||||||
fmt.Println(eapsedTime)
|
fmt.Println(eapsedTime)
|
||||||
|
|
||||||
w.Reset()
|
w.Reset()
|
||||||
|
|
||||||
fmt.Println(w.excuting) //false
|
fmt.Println(w.excuting) //false
|
||||||
|
|
||||||
fmt.Println(w.startTime) //0
|
fmt.Println(w.startTime) //0
|
||||||
fmt.Println(w.stopTime) //0
|
fmt.Println(w.stopTime) //0
|
||||||
}
|
}
|
||||||
|
|
||||||
func longRunningTask() {
|
func longRunningTask() {
|
||||||
var slice []int64
|
var slice []int64
|
||||||
for i := 0; i < 10000000; i++ {
|
for i := 0; i < 10000000; i++ {
|
||||||
slice = append(slice, int64(i))
|
slice = append(slice, int64(i))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
304
docs/maputil.md
304
docs/maputil.md
@@ -1,304 +0,0 @@
|
|||||||
# Maputil
|
|
||||||
Package maputil includes some functions to manipulate map.
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
|
||||||
|
|
||||||
## Source:
|
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/maputil/maputil.go](https://github.com/duke-git/lancet/blob/main/maputil/maputil.go)
|
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
|
||||||
|
|
||||||
## Example:
|
|
||||||
```go
|
|
||||||
import (
|
|
||||||
"github.com/duke-git/lancet/v2/maputil"
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
|
||||||
|
|
||||||
## Index
|
|
||||||
- [ForEach](#ForEach)
|
|
||||||
- [Filter](#Filter)
|
|
||||||
- [Intersect](#Intersect)
|
|
||||||
- [Keys](#Keys)
|
|
||||||
- [Merge](#Merge)
|
|
||||||
- [Minus](#Minus)
|
|
||||||
- [Values](#Values)
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
|
||||||
|
|
||||||
## Documentation
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ForEach">ForEach</span>
|
|
||||||
<p>Executes iteratee funcation for every key and value pair in map.</p>
|
|
||||||
|
|
||||||
<b>Signature:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
func ForEach[K comparable, V any](m map[K]V, iteratee func(key K, value V))
|
|
||||||
```
|
|
||||||
<b>Example:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/duke-git/lancet/v2/maputil"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
m := map[string]int{
|
|
||||||
"a": 1,
|
|
||||||
"b": 2,
|
|
||||||
"c": 3,
|
|
||||||
"d": 4,
|
|
||||||
}
|
|
||||||
|
|
||||||
var sum int
|
|
||||||
|
|
||||||
maputil.ForEach(m, func(_ string, value int) {
|
|
||||||
sum += value
|
|
||||||
})
|
|
||||||
fmt.Println(sum) // 10
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Filter">Filter</span>
|
|
||||||
<p>Iterates over map, return a new map contains all key and value pairs pass the predicate function.</p>
|
|
||||||
|
|
||||||
<b>Signature:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
func Filter[K comparable, V any](m map[K]V, predicate func(key K, value V) bool) map[K]V
|
|
||||||
```
|
|
||||||
<b>Example:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/duke-git/lancet/v2/maputil"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
m := map[string]int{
|
|
||||||
"a": 1,
|
|
||||||
"b": 2,
|
|
||||||
"c": 3,
|
|
||||||
"d": 4,
|
|
||||||
"e": 5,
|
|
||||||
}
|
|
||||||
isEven := func(_ string, value int) bool {
|
|
||||||
return value%2 == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
maputil.Filter(m, func(_ string, value int) {
|
|
||||||
sum += value
|
|
||||||
})
|
|
||||||
res := maputil.Filter(m, isEven)
|
|
||||||
fmt.Println(res) // map[string]int{"b": 2, "d": 4,}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Intersect">Intersect</span>
|
|
||||||
<p>Iterates over maps, return a new map of key and value pairs in all given maps.</p>
|
|
||||||
|
|
||||||
<b>Signature:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
func Intersect[K comparable, V any](maps ...map[K]V) map[K]V
|
|
||||||
```
|
|
||||||
<b>Example:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/duke-git/lancet/v2/maputil"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
m1 := map[string]int{
|
|
||||||
"a": 1,
|
|
||||||
"b": 2,
|
|
||||||
"c": 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
m2 := map[string]int{
|
|
||||||
"a": 1,
|
|
||||||
"b": 2,
|
|
||||||
"c": 6,
|
|
||||||
"d": 7,
|
|
||||||
}
|
|
||||||
|
|
||||||
m3 := map[string]int{
|
|
||||||
"a": 1,
|
|
||||||
"b": 9,
|
|
||||||
"e": 9,
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(maputil.Intersect(m1)) // map[string]int{"a": 1, "b": 2, "c": 3}
|
|
||||||
|
|
||||||
fmt.Println(maputil.Intersect(m1, m2)) // map[string]int{"a": 1, "b": 2}
|
|
||||||
|
|
||||||
fmt.Println(maputil.Intersect(m1, m2, m3)) // map[string]int{"a": 1}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Keys">Keys</span>
|
|
||||||
<p>Returns a slice of the map's keys.</p>
|
|
||||||
|
|
||||||
<b>Signature:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
func Keys[K comparable, V any](m map[K]V) []K
|
|
||||||
```
|
|
||||||
<b>Example:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/duke-git/lancet/v2/maputil"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
m := map[int]string{
|
|
||||||
1: "a",
|
|
||||||
2: "a",
|
|
||||||
3: "b",
|
|
||||||
4: "c",
|
|
||||||
5: "d",
|
|
||||||
}
|
|
||||||
|
|
||||||
keys := maputil.Keys(m)
|
|
||||||
sort.Ints(keys)
|
|
||||||
fmt.Println(keys) // []int{1, 2, 3, 4, 5}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Merge">Merge</span>
|
|
||||||
<p>Merge maps, next key will overwrite previous key.</p>
|
|
||||||
|
|
||||||
<b>Signature:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
func Merge[K comparable, V any](maps ...map[K]V) map[K]V
|
|
||||||
```
|
|
||||||
<b>Example:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/duke-git/lancet/v2/maputil"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
m1 := map[int]string{
|
|
||||||
1: "a",
|
|
||||||
2: "b",
|
|
||||||
}
|
|
||||||
m2 := map[int]string{
|
|
||||||
1: "1",
|
|
||||||
3: "2",
|
|
||||||
}
|
|
||||||
fmt.Println(maputil.Merge(m1, m2)) // map[int]string{1:"1", 2:"b", 3:"2",}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Minus">Minus</span>
|
|
||||||
<p>Creates an map of whose key in mapA but not in mapB.</p>
|
|
||||||
|
|
||||||
<b>Signature:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
func Minus[K comparable, V any](mapA, mapB map[K]V) map[K]V
|
|
||||||
```
|
|
||||||
<b>Example:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/duke-git/lancet/v2/maputil"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
m1 := map[string]int{
|
|
||||||
"a": 1,
|
|
||||||
"b": 2,
|
|
||||||
"c": 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
m2 := map[string]int{
|
|
||||||
"a": 11,
|
|
||||||
"b": 22,
|
|
||||||
"d": 33,
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(maputil.Minus(m1, m2)) //map[string]int{"c": 3}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Values">Values</span>
|
|
||||||
<p>Returns a slice of the map's values.</p>
|
|
||||||
|
|
||||||
<b>Signature:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
func Values[K comparable, V any](m map[K]V) []V
|
|
||||||
```
|
|
||||||
<b>Example:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/duke-git/lancet/v2/maputil"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
m := map[int]string{
|
|
||||||
1: "a",
|
|
||||||
2: "a",
|
|
||||||
3: "b",
|
|
||||||
4: "c",
|
|
||||||
5: "d",
|
|
||||||
}
|
|
||||||
|
|
||||||
values := maputil.Values(m)
|
|
||||||
sort.Strings(values)
|
|
||||||
|
|
||||||
fmt.Println(values) // []string{"a", "a", "b", "c", "d"}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
@@ -1,304 +0,0 @@
|
|||||||
# Maputil
|
|
||||||
maputil包包括一些操作map的函数。
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
|
||||||
|
|
||||||
## 源码:
|
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/maputil/maputil.go](https://github.com/duke-git/lancet/blob/main/maputil/maputil.go)
|
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
|
||||||
|
|
||||||
## 用法:
|
|
||||||
```go
|
|
||||||
import (
|
|
||||||
"github.com/duke-git/lancet/v2/maputil"
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
|
||||||
|
|
||||||
## 目录:
|
|
||||||
- [ForEach](#ForEach)
|
|
||||||
- [Filter](#Filter)
|
|
||||||
- [Intersect](#Intersect)
|
|
||||||
- [Keys](#Keys)
|
|
||||||
- [Merge](#Merge)
|
|
||||||
- [Minus](#Minus)
|
|
||||||
- [Values](#Values)
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
|
||||||
|
|
||||||
## API文档:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ForEach">ForEach</span>
|
|
||||||
<p>对map中的每对key和value执行iteratee函数</p>
|
|
||||||
|
|
||||||
<b>函数签名:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
func ForEach[K comparable, V any](m map[K]V, iteratee func(key K, value V))
|
|
||||||
```
|
|
||||||
<b>例子:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/duke-git/lancet/v2/maputil"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
m := map[string]int{
|
|
||||||
"a": 1,
|
|
||||||
"b": 2,
|
|
||||||
"c": 3,
|
|
||||||
"d": 4,
|
|
||||||
}
|
|
||||||
|
|
||||||
var sum int
|
|
||||||
|
|
||||||
maputil.ForEach(m, func(_ string, value int) {
|
|
||||||
sum += value
|
|
||||||
})
|
|
||||||
fmt.Println(sum) // 10
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Filter">Filter</span>
|
|
||||||
<p>迭代map中的每对key和value, 返回符合predicate函数的key, value</p>
|
|
||||||
|
|
||||||
<b>函数签名:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
func Filter[K comparable, V any](m map[K]V, predicate func(key K, value V) bool) map[K]V
|
|
||||||
```
|
|
||||||
<b>例子:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/duke-git/lancet/v2/maputil"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
m := map[string]int{
|
|
||||||
"a": 1,
|
|
||||||
"b": 2,
|
|
||||||
"c": 3,
|
|
||||||
"d": 4,
|
|
||||||
"e": 5,
|
|
||||||
}
|
|
||||||
isEven := func(_ string, value int) bool {
|
|
||||||
return value%2 == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
maputil.Filter(m, func(_ string, value int) {
|
|
||||||
sum += value
|
|
||||||
})
|
|
||||||
res := maputil.Filter(m, isEven)
|
|
||||||
fmt.Println(res) // map[string]int{"b": 2, "d": 4,}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Intersect">Intersect</span>
|
|
||||||
<p>多个map的交集操作</p>
|
|
||||||
|
|
||||||
<b>函数签名:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
func Intersect[K comparable, V any](maps ...map[K]V) map[K]V
|
|
||||||
```
|
|
||||||
<b>例子:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/duke-git/lancet/v2/maputil"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
m1 := map[string]int{
|
|
||||||
"a": 1,
|
|
||||||
"b": 2,
|
|
||||||
"c": 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
m2 := map[string]int{
|
|
||||||
"a": 1,
|
|
||||||
"b": 2,
|
|
||||||
"c": 6,
|
|
||||||
"d": 7,
|
|
||||||
}
|
|
||||||
|
|
||||||
m3 := map[string]int{
|
|
||||||
"a": 1,
|
|
||||||
"b": 9,
|
|
||||||
"e": 9,
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(maputil.Intersect(m1)) // map[string]int{"a": 1, "b": 2, "c": 3}
|
|
||||||
|
|
||||||
fmt.Println(maputil.Intersect(m1, m2)) // map[string]int{"a": 1, "b": 2}
|
|
||||||
|
|
||||||
fmt.Println(maputil.Intersect(m1, m2, m3)) // map[string]int{"a": 1}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Keys">Keys</span>
|
|
||||||
<p>返回map中所有key的切片</p>
|
|
||||||
|
|
||||||
<b>函数签名:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
func Keys[K comparable, V any](m map[K]V) []K
|
|
||||||
```
|
|
||||||
<b>例子:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/duke-git/lancet/v2/maputil"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
m := map[int]string{
|
|
||||||
1: "a",
|
|
||||||
2: "a",
|
|
||||||
3: "b",
|
|
||||||
4: "c",
|
|
||||||
5: "d",
|
|
||||||
}
|
|
||||||
|
|
||||||
keys := maputil.Keys(m)
|
|
||||||
sort.Ints(keys)
|
|
||||||
fmt.Println(keys) // []int{1, 2, 3, 4, 5}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Merge">Merge</span>
|
|
||||||
<p>合并多个maps, 相同的key会被后来的key覆盖</p>
|
|
||||||
|
|
||||||
<b>函数签名:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
func Merge[K comparable, V any](maps ...map[K]V) map[K]V
|
|
||||||
```
|
|
||||||
<b>例子:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/duke-git/lancet/v2/maputil"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
m1 := map[int]string{
|
|
||||||
1: "a",
|
|
||||||
2: "b",
|
|
||||||
}
|
|
||||||
m2 := map[int]string{
|
|
||||||
1: "1",
|
|
||||||
3: "2",
|
|
||||||
}
|
|
||||||
fmt.Println(maputil.Merge(m1, m2)) // map[int]string{1:"1", 2:"b", 3:"2",}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Minus">Minus</span>
|
|
||||||
<p>返回一个map,其中的key存在于mapA,不存在于mapB.</p>
|
|
||||||
|
|
||||||
<b>函数签名:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
func Minus[K comparable, V any](mapA, mapB map[K]V) map[K]V
|
|
||||||
```
|
|
||||||
<b>例子:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/duke-git/lancet/v2/maputil"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
m1 := map[string]int{
|
|
||||||
"a": 1,
|
|
||||||
"b": 2,
|
|
||||||
"c": 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
m2 := map[string]int{
|
|
||||||
"a": 11,
|
|
||||||
"b": 22,
|
|
||||||
"d": 33,
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(maputil.Minus(m1, m2)) //map[string]int{"c": 3}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Values">Values</span>
|
|
||||||
<p>返回map中所有value的切片</p>
|
|
||||||
|
|
||||||
<b>函数签名:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
func Values[K comparable, V any](m map[K]V) []V
|
|
||||||
```
|
|
||||||
<b>例子:</b>
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/duke-git/lancet/v2/maputil"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
m := map[int]string{
|
|
||||||
1: "a",
|
|
||||||
2: "a",
|
|
||||||
3: "b",
|
|
||||||
4: "c",
|
|
||||||
5: "d",
|
|
||||||
}
|
|
||||||
|
|
||||||
values := maputil.Values(m)
|
|
||||||
sort.Strings(values)
|
|
||||||
|
|
||||||
fmt.Println(values) // []string{"a", "a", "b", "c", "d"}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
552
docs/mathutil.md
552
docs/mathutil.md
@@ -1,72 +1,50 @@
|
|||||||
# Mathutil
|
# Mathutil
|
||||||
|
|
||||||
Package mathutil implements some functions for math calculation.
|
Package mathutil implements some functions for math calculation.
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Source:
|
## Source:
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go)
|
[https://github.com/duke-git/lancet/blob/v1/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/v1/mathutil/mathutil.go)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Example:
|
## Example:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/v2/mathutil"
|
"github.com/duke-git/lancet/mathutil"
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Index
|
## Index
|
||||||
- [Average](#Average)
|
|
||||||
- [Exponent](#Exponent)
|
|
||||||
- [Fibonacci](#Fibonacci)
|
|
||||||
- [Factorial](#Factorial)
|
|
||||||
- [Max](#Max)
|
|
||||||
- [Min](#Min)
|
|
||||||
|
|
||||||
- [Percent](#Percent)
|
- [Exponent](#Exponent)
|
||||||
- [RoundToFloat](#RoundToFloat)
|
- [Fibonacci](#Fibonacci)
|
||||||
- [RoundToString](#RoundToString)
|
- [Factorial](#Factorial)
|
||||||
- [TruncRound](#TruncRound)
|
- [Percent](#Percent)
|
||||||
|
- [RoundToFloat](#RoundToFloat)
|
||||||
|
- [RoundToString](#RoundToString)
|
||||||
|
- [TruncRound](#TruncRound)
|
||||||
|
- [AngleToRadian](#AngleToRadian)
|
||||||
|
- [RadianToAngle](#RadianToAngle)
|
||||||
|
- [PointDistance](#PointDistance)
|
||||||
|
- [IsPrime](#IsPrime)
|
||||||
|
- [GCD](#GCD)
|
||||||
|
- [LCM](#LCM)
|
||||||
|
- [Cos](#Cos)
|
||||||
|
- [Sin](#Sin)
|
||||||
|
- [Log](#Log)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Documentation
|
## 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>
|
### <span id="Exponent">Exponent</span>
|
||||||
|
|
||||||
<p>Calculate x to the nth power.</p>
|
<p>Calculate x to the nth power.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -74,6 +52,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Exponent(x, n int64) int64
|
func Exponent(x, n int64) int64
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -81,19 +60,18 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/mathutil"
|
"github.com/duke-git/lancet/mathutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println(mathutil.Exponent(10, 0)) //1
|
fmt.Println(mathutil.Exponent(10, 0)) //1
|
||||||
fmt.Println(mathutil.Exponent(10, 1)) //10
|
fmt.Println(mathutil.Exponent(10, 1)) //10
|
||||||
fmt.Println(mathutil.Exponent(10, 2)) //100
|
fmt.Println(mathutil.Exponent(10, 2)) //100
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Fibonacci">Fibonacci</span>
|
### <span id="Fibonacci">Fibonacci</span>
|
||||||
|
|
||||||
<p>Calculate the nth number of fibonacci sequence.</p>
|
<p>Calculate the nth number of fibonacci sequence.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -101,6 +79,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Fibonacci(first, second, n int) int
|
func Fibonacci(first, second, n int) int
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -108,21 +87,20 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/mathutil"
|
"github.com/duke-git/lancet/mathutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println(mathutil.Fibonacci(1, 1, 1)) //1
|
fmt.Println(mathutil.Fibonacci(1, 1, 1)) //1
|
||||||
fmt.Println(mathutil.Fibonacci(1, 1, 2)) //1
|
fmt.Println(mathutil.Fibonacci(1, 1, 2)) //1
|
||||||
fmt.Println(mathutil.Fibonacci(1, 1, 3)) //2
|
fmt.Println(mathutil.Fibonacci(1, 1, 3)) //2
|
||||||
fmt.Println(mathutil.Fibonacci(1, 1, 4)) //3
|
fmt.Println(mathutil.Fibonacci(1, 1, 4)) //3
|
||||||
fmt.Println(mathutil.Fibonacci(1, 1, 5)) //5
|
fmt.Println(mathutil.Fibonacci(1, 1, 5)) //5
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Factorial">Factorial</span>
|
### <span id="Factorial">Factorial</span>
|
||||||
|
|
||||||
<p>Calculate the factorial of x.</p>
|
<p>Calculate the factorial of x.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -130,6 +108,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Factorial(x uint) uint
|
func Factorial(x uint) uint
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -137,74 +116,19 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/mathutil"
|
"github.com/duke-git/lancet/mathutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println(mathutil.Factorial(0)) //1
|
fmt.Println(mathutil.Factorial(0)) //1
|
||||||
fmt.Println(mathutil.Factorial(1)) //1
|
fmt.Println(mathutil.Factorial(1)) //1
|
||||||
fmt.Println(mathutil.Factorial(2)) //2
|
fmt.Println(mathutil.Factorial(2)) //2
|
||||||
fmt.Println(mathutil.Factorial(3)) //6
|
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>
|
### <span id="Percent">Percent</span>
|
||||||
|
|
||||||
<p>calculate the percentage of val to total, retain n decimal places.</p>
|
<p>calculate the percentage of val to total, retain n decimal places.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -212,6 +136,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Percent(val, total float64, n int) float64
|
func Percent(val, total float64, n int) float64
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -219,18 +144,17 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/mathutil"
|
"github.com/duke-git/lancet/mathutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println(mathutil.Percent(1, 2, 2)) //1
|
fmt.Println(mathutil.Percent(1, 2, 2)) //1
|
||||||
fmt.Println(mathutil.Percent(0.1, 0.3, 2)) //33.33
|
fmt.Println(mathutil.Percent(0.1, 0.3, 2)) //33.33
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="RoundToFloat">RoundToFloat</span>
|
### <span id="RoundToFloat">RoundToFloat</span>
|
||||||
|
|
||||||
<p>Round float up to n decimal places.</p>
|
<p>Round float up to n decimal places.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -238,6 +162,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func RoundToFloat(x float64, n int) float64
|
func RoundToFloat(x float64, n int) float64
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -245,22 +170,20 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/mathutil"
|
"github.com/duke-git/lancet/mathutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println(mathutil.RoundToFloat(0, 0)) //0
|
fmt.Println(mathutil.RoundToFloat(0, 0)) //0
|
||||||
fmt.Println(mathutil.RoundToFloat(0, 1)) //0
|
fmt.Println(mathutil.RoundToFloat(0, 1)) //0
|
||||||
fmt.Println(mathutil.RoundToFloat(0.124, 2)) //0.12
|
fmt.Println(mathutil.RoundToFloat(0.124, 2)) //0.12
|
||||||
fmt.Println(mathutil.RoundToFloat(0.125, 2)) //0.13
|
fmt.Println(mathutil.RoundToFloat(0.125, 2)) //0.13
|
||||||
fmt.Println(mathutil.RoundToFloat(0.125, 3)) //0.125
|
fmt.Println(mathutil.RoundToFloat(0.125, 3)) //0.125
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="RoundToString">RoundToString</span>
|
### <span id="RoundToString">RoundToString</span>
|
||||||
|
|
||||||
<p>Round float up to n decimal places. will return string.</p>
|
<p>Round float up to n decimal places. will return string.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -268,6 +191,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func RoundToString(x float64, n int) string
|
func RoundToString(x float64, n int) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -275,21 +199,20 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/mathutil"
|
"github.com/duke-git/lancet/mathutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println(mathutil.RoundToString(0, 0)) //"0"
|
fmt.Println(mathutil.RoundToString(0, 0)) //"0"
|
||||||
fmt.Println(mathutil.RoundToString(0, 1)) //"0.0:
|
fmt.Println(mathutil.RoundToString(0, 1)) //"0.0:
|
||||||
fmt.Println(mathutil.RoundToString(0.124, 2)) //"0.12"
|
fmt.Println(mathutil.RoundToString(0.124, 2)) //"0.12"
|
||||||
fmt.Println(mathutil.RoundToString(0.125, 2)) //"0.13"
|
fmt.Println(mathutil.RoundToString(0.125, 2)) //"0.13"
|
||||||
fmt.Println(mathutil.RoundToString(0.125, 3)) //"0.125"
|
fmt.Println(mathutil.RoundToString(0.125, 3)) //"0.125"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="TruncRound">TruncRound</span>
|
### <span id="TruncRound">TruncRound</span>
|
||||||
|
|
||||||
<p>Round float off n decimal places.</p>
|
<p>Round float off n decimal places.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -297,6 +220,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func TruncRound(x float64, n int) float64
|
func TruncRound(x float64, n int) float64
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -304,17 +228,353 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/mathutil"
|
"github.com/duke-git/lancet/mathutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println(mathutil.TruncRound(0, 0)) //0
|
fmt.Println(mathutil.TruncRound(0, 0)) //0
|
||||||
fmt.Println(mathutil.TruncRound(0, 1)) //0
|
fmt.Println(mathutil.TruncRound(0, 1)) //0
|
||||||
fmt.Println(mathutil.TruncRound(0.124, 2)) //0.12
|
fmt.Println(mathutil.TruncRound(0.124, 2)) //0.12
|
||||||
fmt.Println(mathutil.TruncRound(0.125, 2)) //0.12
|
fmt.Println(mathutil.TruncRound(0.125, 2)) //0.12
|
||||||
fmt.Println(mathutil.TruncRound(0.125, 3)) //0.125
|
fmt.Println(mathutil.TruncRound(0.125, 3)) //0.125
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="AngleToRadian">AngleToRadian</span>
|
||||||
|
|
||||||
|
<p>Converts angle value to radian value.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func AngleToRadian(angle float64) float64
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/mathutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := mathutil.AngleToRadian(45)
|
||||||
|
result2 := mathutil.AngleToRadian(90)
|
||||||
|
result3 := mathutil.AngleToRadian(180)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 0.7853981633974483
|
||||||
|
// 1.5707963267948966
|
||||||
|
// 3.141592653589793
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="RadianToAngle">RadianToAngle</span>
|
||||||
|
|
||||||
|
<p>Converts radian value to angle value.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RadianToAngle(radian float64) float64
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/mathutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := mathutil.RadianToAngle(math.Pi)
|
||||||
|
result2 := mathutil.RadianToAngle(math.Pi / 2)
|
||||||
|
result3 := mathutil.RadianToAngle(math.Pi / 4)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 180
|
||||||
|
// 90
|
||||||
|
// 45
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="PointDistance">PointDistance</span>
|
||||||
|
|
||||||
|
<p>Caculates two points distance.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func PointDistance(x1, y1, x2, y2 float64) float64
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/mathutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := mathutil.PointDistance(1, 1, 4, 5)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 5
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="IsPrime">IsPrime</span>
|
||||||
|
|
||||||
|
<p>Checks if number is prime number.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func IsPrime(n int) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/mathutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := mathutil.IsPrime(-1)
|
||||||
|
result2 := mathutil.IsPrime(0)
|
||||||
|
result3 := mathutil.IsPrime(1)
|
||||||
|
result4 := mathutil.IsPrime(2)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
// true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="GCD">GCD</span>
|
||||||
|
|
||||||
|
<p>Return greatest common divisor (GCD) of integers.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GCD(integers ...int) int
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/mathutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := mathutil.GCD(1, 1)
|
||||||
|
result2 := mathutil.GCD(1, -1)
|
||||||
|
result3 := mathutil.GCD(-1, 1)
|
||||||
|
result4 := mathutil.GCD(-1, -1)
|
||||||
|
result5 := mathutil.GCD(3, 6, 9)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
fmt.Println(result5)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1
|
||||||
|
// 1
|
||||||
|
// -1
|
||||||
|
// -1
|
||||||
|
// 3
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="LCM">LCM</span>
|
||||||
|
|
||||||
|
<p>Return Least Common Multiple (LCM) of integers.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func LCM(integers ...int) int
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/mathutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := mathutil.LCM(1, 1)
|
||||||
|
result2 := mathutil.LCM(1, 2)
|
||||||
|
result3 := mathutil.LCM(3, 6, 9)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1
|
||||||
|
// 2
|
||||||
|
// 18
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Cos">Cos</span>
|
||||||
|
|
||||||
|
<p>Returns the cosine of the radian argument.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Cos(radian float64, precision ...int) float64
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/mathutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := mathutil.Cos(0)
|
||||||
|
result2 := mathutil.Cos(90)
|
||||||
|
result3 := mathutil.Cos(180)
|
||||||
|
result4 := mathutil.Cos(math.Pi)
|
||||||
|
result5 := mathutil.Cos(math.Pi / 2)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
fmt.Println(result5)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1
|
||||||
|
// -0.447
|
||||||
|
// -0.598
|
||||||
|
// -1
|
||||||
|
// 0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Sin">Sin</span>
|
||||||
|
|
||||||
|
<p>Returns the sine of the radian argument.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Sin(radian float64, precision ...int) float64
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/mathutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := mathutil.Sin(0)
|
||||||
|
result2 := mathutil.Sin(90)
|
||||||
|
result3 := mathutil.Sin(180)
|
||||||
|
result4 := mathutil.Sin(math.Pi)
|
||||||
|
result5 := mathutil.Sin(math.Pi / 2)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
fmt.Println(result5)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 0
|
||||||
|
// 0.894
|
||||||
|
// -0.801
|
||||||
|
// 0
|
||||||
|
// 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Log">Log</span>
|
||||||
|
|
||||||
|
<p>Returns the logarithm of base n.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Log(n, base float64) float64
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/mathutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := mathutil.Log(8, 2)
|
||||||
|
result2 := mathutil.TruncRound(mathutil.Log(5, 2), 2)
|
||||||
|
result3 := mathutil.TruncRound(mathutil.Log(27, 3), 0)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 3
|
||||||
|
// 2.32
|
||||||
|
// 3
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,70 +1,50 @@
|
|||||||
# Mathutil
|
# Mathutil
|
||||||
mathutil包实现了一些数学计算的函数.
|
|
||||||
|
mathutil 包实现了一些数学计算的函数.
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 源码:
|
## 源码:
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go)
|
[https://github.com/duke-git/lancet/blob/v1/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/v1/mathutil/mathutil.go)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 用法:
|
## 用法:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/v2/mathutil"
|
"github.com/duke-git/lancet/mathutil"
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 目录
|
## 目录
|
||||||
- [Average](#Average)
|
|
||||||
- [Exponent](#Exponent)
|
- [Exponent](#Exponent)
|
||||||
- [Fibonacci](#Fibonacci)
|
- [Fibonacci](#Fibonacci)
|
||||||
- [Factorial](#Factorial)
|
- [Factorial](#Factorial)
|
||||||
- [Max](#Max)
|
- [Percent](#Percent)
|
||||||
- [Min](#Min)
|
- [RoundToFloat](#RoundToFloat)
|
||||||
|
- [RoundToString](#RoundToString)
|
||||||
- [Percent](#Percent)
|
- [TruncRound](#TruncRound)
|
||||||
- [RoundToFloat](#RoundToFloat)
|
- [AngleToRadian](#AngleToRadian)
|
||||||
- [RoundToString](#RoundToString)
|
- [RadianToAngle](#RadianToAngle)
|
||||||
- [TruncRound](#TruncRound)
|
- [PointDistance](#PointDistance)
|
||||||
|
- [IsPrime](#IsPrime)
|
||||||
|
- [GCD](#GCD)
|
||||||
|
- [LCM](#LCM)
|
||||||
|
- [Cos](#Cos)
|
||||||
|
- [Sin](#Sin)
|
||||||
|
- [Log](#Log)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Documentation
|
## 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>
|
### <span id="Exponent">Exponent</span>
|
||||||
|
|
||||||
<p>指数计算(x的n次方)</p>
|
<p>指数计算(x的n次方)</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -72,6 +52,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Exponent(x, n int64) int64
|
func Exponent(x, n int64) int64
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -79,19 +60,18 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/mathutil"
|
"github.com/duke-git/lancet/mathutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println(mathutil.Exponent(10, 0)) //1
|
fmt.Println(mathutil.Exponent(10, 0)) //1
|
||||||
fmt.Println(mathutil.Exponent(10, 1)) //10
|
fmt.Println(mathutil.Exponent(10, 1)) //10
|
||||||
fmt.Println(mathutil.Exponent(10, 2)) //100
|
fmt.Println(mathutil.Exponent(10, 2)) //100
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Fibonacci">Fibonacci</span>
|
### <span id="Fibonacci">Fibonacci</span>
|
||||||
|
|
||||||
<p>计算斐波那契数列的第n个数</p>
|
<p>计算斐波那契数列的第n个数</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -99,6 +79,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Fibonacci(first, second, n int) int
|
func Fibonacci(first, second, n int) int
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -106,21 +87,20 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/mathutil"
|
"github.com/duke-git/lancet/mathutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println(mathutil.Fibonacci(1, 1, 1)) //1
|
fmt.Println(mathutil.Fibonacci(1, 1, 1)) //1
|
||||||
fmt.Println(mathutil.Fibonacci(1, 1, 2)) //1
|
fmt.Println(mathutil.Fibonacci(1, 1, 2)) //1
|
||||||
fmt.Println(mathutil.Fibonacci(1, 1, 3)) //2
|
fmt.Println(mathutil.Fibonacci(1, 1, 3)) //2
|
||||||
fmt.Println(mathutil.Fibonacci(1, 1, 4)) //3
|
fmt.Println(mathutil.Fibonacci(1, 1, 4)) //3
|
||||||
fmt.Println(mathutil.Fibonacci(1, 1, 5)) //5
|
fmt.Println(mathutil.Fibonacci(1, 1, 5)) //5
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Factorial">Factorial</span>
|
### <span id="Factorial">Factorial</span>
|
||||||
|
|
||||||
<p>计算阶乘</p>
|
<p>计算阶乘</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -128,6 +108,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Factorial(x uint) uint
|
func Factorial(x uint) uint
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -135,73 +116,19 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/mathutil"
|
"github.com/duke-git/lancet/mathutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println(mathutil.Factorial(0)) //1
|
fmt.Println(mathutil.Factorial(0)) //1
|
||||||
fmt.Println(mathutil.Factorial(1)) //1
|
fmt.Println(mathutil.Factorial(1)) //1
|
||||||
fmt.Println(mathutil.Factorial(2)) //2
|
fmt.Println(mathutil.Factorial(2)) //2
|
||||||
fmt.Println(mathutil.Factorial(3)) //6
|
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>
|
### <span id="Percent">Percent</span>
|
||||||
|
|
||||||
<p>计算百分比,保留n位小数</p>
|
<p>计算百分比,保留n位小数</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -209,6 +136,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Percent(val, total float64, n int) float64
|
func Percent(val, total float64, n int) float64
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -216,18 +144,17 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/mathutil"
|
"github.com/duke-git/lancet/mathutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println(mathutil.Percent(1, 2, 2)) //1
|
fmt.Println(mathutil.Percent(1, 2, 2)) //1
|
||||||
fmt.Println(mathutil.Percent(0.1, 0.3, 2)) //33.33
|
fmt.Println(mathutil.Percent(0.1, 0.3, 2)) //33.33
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="RoundToFloat">RoundToFloat</span>
|
### <span id="RoundToFloat">RoundToFloat</span>
|
||||||
|
|
||||||
<p>四舍五入,保留n位小数</p>
|
<p>四舍五入,保留n位小数</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -235,6 +162,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func RoundToFloat(x float64, n int) float64
|
func RoundToFloat(x float64, n int) float64
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -242,22 +170,20 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/mathutil"
|
"github.com/duke-git/lancet/mathutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println(mathutil.RoundToFloat(0, 0)) //0
|
fmt.Println(mathutil.RoundToFloat(0, 0)) //0
|
||||||
fmt.Println(mathutil.RoundToFloat(0, 1)) //0
|
fmt.Println(mathutil.RoundToFloat(0, 1)) //0
|
||||||
fmt.Println(mathutil.RoundToFloat(0.124, 2)) //0.12
|
fmt.Println(mathutil.RoundToFloat(0.124, 2)) //0.12
|
||||||
fmt.Println(mathutil.RoundToFloat(0.125, 2)) //0.13
|
fmt.Println(mathutil.RoundToFloat(0.125, 2)) //0.13
|
||||||
fmt.Println(mathutil.RoundToFloat(0.125, 3)) //0.125
|
fmt.Println(mathutil.RoundToFloat(0.125, 3)) //0.125
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="RoundToString">RoundToString</span>
|
### <span id="RoundToString">RoundToString</span>
|
||||||
|
|
||||||
<p>四舍五入,保留n位小数,返回字符串</p>
|
<p>四舍五入,保留n位小数,返回字符串</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -265,6 +191,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func RoundToString(x float64, n int) string
|
func RoundToString(x float64, n int) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -272,21 +199,20 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/mathutil"
|
"github.com/duke-git/lancet/mathutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println(mathutil.RoundToString(0, 0)) //"0"
|
fmt.Println(mathutil.RoundToString(0, 0)) //"0"
|
||||||
fmt.Println(mathutil.RoundToString(0, 1)) //"0.0:
|
fmt.Println(mathutil.RoundToString(0, 1)) //"0.0:
|
||||||
fmt.Println(mathutil.RoundToString(0.124, 2)) //"0.12"
|
fmt.Println(mathutil.RoundToString(0.124, 2)) //"0.12"
|
||||||
fmt.Println(mathutil.RoundToString(0.125, 2)) //"0.13"
|
fmt.Println(mathutil.RoundToString(0.125, 2)) //"0.13"
|
||||||
fmt.Println(mathutil.RoundToString(0.125, 3)) //"0.125"
|
fmt.Println(mathutil.RoundToString(0.125, 3)) //"0.125"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="TruncRound">TruncRound</span>
|
### <span id="TruncRound">TruncRound</span>
|
||||||
|
|
||||||
<p>截短n位小数(不进行四舍五入)</p>
|
<p>截短n位小数(不进行四舍五入)</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -294,6 +220,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func TruncRound(x float64, n int) float64
|
func TruncRound(x float64, n int) float64
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -301,17 +228,356 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/mathutil"
|
"github.com/duke-git/lancet/mathutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println(mathutil.TruncRound(0, 0)) //0
|
fmt.Println(mathutil.TruncRound(0, 0)) //0
|
||||||
fmt.Println(mathutil.TruncRound(0, 1)) //0
|
fmt.Println(mathutil.TruncRound(0, 1)) //0
|
||||||
fmt.Println(mathutil.TruncRound(0.124, 2)) //0.12
|
fmt.Println(mathutil.TruncRound(0.124, 2)) //0.12
|
||||||
fmt.Println(mathutil.TruncRound(0.125, 2)) //0.12
|
fmt.Println(mathutil.TruncRound(0.125, 2)) //0.12
|
||||||
fmt.Println(mathutil.TruncRound(0.125, 3)) //0.125
|
fmt.Println(mathutil.TruncRound(0.125, 3)) //0.125
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="AngleToRadian">AngleToRadian</span>
|
||||||
|
|
||||||
|
<p>将角度值转为弧度值</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func AngleToRadian(angle float64) float64
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/mathutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := mathutil.AngleToRadian(45)
|
||||||
|
result2 := mathutil.AngleToRadian(90)
|
||||||
|
result3 := mathutil.AngleToRadian(180)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 0.7853981633974483
|
||||||
|
// 1.5707963267948966
|
||||||
|
// 3.141592653589793
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="RadianToAngle">RadianToAngle</span>
|
||||||
|
|
||||||
|
<p>将弧度值转为角度值</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RadianToAngle(radian float64) float64
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/mathutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := mathutil.RadianToAngle(math.Pi)
|
||||||
|
result2 := mathutil.RadianToAngle(math.Pi / 2)
|
||||||
|
result3 := mathutil.RadianToAngle(math.Pi / 4)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 180
|
||||||
|
// 90
|
||||||
|
// 45
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="PointDistance">PointDistance</span>
|
||||||
|
|
||||||
|
<p>计算两个坐标点的距离</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func PointDistance(x1, y1, x2, y2 float64) float64
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/mathutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := mathutil.PointDistance(1, 1, 4, 5)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 5
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="IsPrime">IsPrime</span>
|
||||||
|
|
||||||
|
<p>判断质数。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func IsPrime(n int) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/mathutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := mathutil.IsPrime(-1)
|
||||||
|
result2 := mathutil.IsPrime(0)
|
||||||
|
result3 := mathutil.IsPrime(1)
|
||||||
|
result4 := mathutil.IsPrime(2)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
// false
|
||||||
|
// true
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="GCD">GCD</span>
|
||||||
|
|
||||||
|
<p>计算整数最大公约数。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GCD(integers ...int) int
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/mathutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := mathutil.GCD(1, 1)
|
||||||
|
result2 := mathutil.GCD(1, -1)
|
||||||
|
result3 := mathutil.GCD(-1, 1)
|
||||||
|
result4 := mathutil.GCD(-1, -1)
|
||||||
|
result5 := mathutil.GCD(3, 6, 9)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
fmt.Println(result5)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1
|
||||||
|
// 1
|
||||||
|
// -1
|
||||||
|
// -1
|
||||||
|
// 3
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="LCM">LCM</span>
|
||||||
|
|
||||||
|
<p>计算整数最小公倍数。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func LCM(integers ...int) int
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/mathutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := mathutil.LCM(1, 1)
|
||||||
|
result2 := mathutil.LCM(1, 2)
|
||||||
|
result3 := mathutil.LCM(3, 6, 9)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1
|
||||||
|
// 2
|
||||||
|
// 18
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Cos">Cos</span>
|
||||||
|
|
||||||
|
<p>计算弧度的余弦值。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Cos(radian float64, precision ...int) float64
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/mathutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := mathutil.Cos(0)
|
||||||
|
result2 := mathutil.Cos(90)
|
||||||
|
result3 := mathutil.Cos(180)
|
||||||
|
result4 := mathutil.Cos(math.Pi)
|
||||||
|
result5 := mathutil.Cos(math.Pi / 2)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
fmt.Println(result5)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1
|
||||||
|
// -0.447
|
||||||
|
// -0.598
|
||||||
|
// -1
|
||||||
|
// 0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="Sin">Sin</span>
|
||||||
|
|
||||||
|
<p>计算弧度的正弦值。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Sin(radian float64, precision ...int) float64
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/mathutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := mathutil.Sin(0)
|
||||||
|
result2 := mathutil.Sin(90)
|
||||||
|
result3 := mathutil.Sin(180)
|
||||||
|
result4 := mathutil.Sin(math.Pi)
|
||||||
|
result5 := mathutil.Sin(math.Pi / 2)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
fmt.Println(result4)
|
||||||
|
fmt.Println(result5)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 0
|
||||||
|
// 0.894
|
||||||
|
// -0.801
|
||||||
|
// 0
|
||||||
|
// 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="Log">Log</span>
|
||||||
|
|
||||||
|
<p>计算以base为底n的对数。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Log(n, base float64) float64
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/mathutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result1 := mathutil.Log(8, 2)
|
||||||
|
result2 := mathutil.TruncRound(mathutil.Log(5, 2), 2)
|
||||||
|
result3 := mathutil.TruncRound(mathutil.Log(27, 3), 0)
|
||||||
|
|
||||||
|
fmt.Println(result1)
|
||||||
|
fmt.Println(result2)
|
||||||
|
fmt.Println(result3)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 3
|
||||||
|
// 2.32
|
||||||
|
// 3
|
||||||
|
}
|
||||||
|
```
|
||||||
888
docs/netutil.md
888
docs/netutil.md
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
184
docs/random.md
184
docs/random.md
@@ -1,36 +1,43 @@
|
|||||||
# Random
|
# Random
|
||||||
|
|
||||||
Package random implements some basic functions to generate random int and string.
|
Package random implements some basic functions to generate random int and string.
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Source:
|
## Source:
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/random/random.go](https://github.com/duke-git/lancet/blob/main/random/random.go)
|
[https://github.com/duke-git/lancet/blob/v1/random/random.go](https://github.com/duke-git/lancet/blob/v1/random/random.go)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Usage:
|
## Usage:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/v2/random"
|
"github.com/duke-git/lancet/random"
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Index
|
## Index
|
||||||
- [RandBytes](#RandBytes)
|
|
||||||
- [RandInt](#RandInt)
|
- [RandBytes](#RandBytes)
|
||||||
- [RandString](#RandString)
|
- [RandInt](#RandInt)
|
||||||
- [UUIdV4](#UUIdV4)
|
- [RandString](#RandString)
|
||||||
|
- [RandUpper](#RandUpper)
|
||||||
|
- [RandLower](#RandLower)
|
||||||
|
- [RandNumeral](#RandNumeral)
|
||||||
|
- [RandNumeralOrLetter](#RandNumeralOrLetter)
|
||||||
|
- [UUIdV4](#UUIdV4)
|
||||||
|
- [RandUniqueIntSlice](#RandUniqueIntSlice)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
|
||||||
### <span id="RandBytes">RandBytes</span>
|
### <span id="RandBytes">RandBytes</span>
|
||||||
|
|
||||||
<p>Generate random byte slice.</p>
|
<p>Generate random byte slice.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -38,6 +45,7 @@ import (
|
|||||||
```go
|
```go
|
||||||
func RandBytes(length int) []byte
|
func RandBytes(length int) []byte
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -45,17 +53,17 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/random"
|
"github.com/duke-git/lancet/random"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
randBytes := random.RandBytes(4)
|
randBytes := random.RandBytes(4)
|
||||||
fmt.Println(randBytes)
|
fmt.Println(randBytes)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="RandInt">RandInt</span>
|
### <span id="RandInt">RandInt</span>
|
||||||
|
|
||||||
<p>Generate random int between min and max, may contain min, not max.</p>
|
<p>Generate random int between min and max, may contain min, not max.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -63,6 +71,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func RandInt(min, max int) int
|
func RandInt(min, max int) int
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -70,25 +79,25 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/random"
|
"github.com/duke-git/lancet/random"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rInt := random.RandInt(1, 10)
|
rInt := random.RandInt(1, 10)
|
||||||
fmt.Println(rInt)
|
fmt.Println(rInt)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="RandString">RandString</span>
|
||||||
|
|
||||||
|
<p>Generate random given length string. only contains letter (a-zA-Z)</p>
|
||||||
### <span id="RandString">RandInt</span>
|
|
||||||
<p>Generate random given length string.</p>
|
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func RandString(length int) string
|
func RandString(length int) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -96,19 +105,121 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/random"
|
"github.com/duke-git/lancet/random"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
randStr := random.RandString(6)
|
randStr := random.RandString(6)
|
||||||
fmt.Println(randStr)
|
fmt.Println(randStr) //pGWsze
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="RandUpper">RandUpper</span>
|
||||||
|
|
||||||
|
<p>Generate a random upper case string</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RandUpper(length int) string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
randStr := random.RandString(6)
|
||||||
|
fmt.Println(randStr) //PACWGF
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="RandLower">RandLower</span>
|
||||||
|
|
||||||
|
<p>Generate a random lower case string</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RandLower(length int) string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
randStr := random.RandLower(6)
|
||||||
|
fmt.Println(randStr) //siqbew
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="RandNumeral">RandNumeral</span>
|
||||||
|
|
||||||
|
<p>Generate a random numeral string</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RandNumeral(length int) string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
randStr := random.RandNumeral(6)
|
||||||
|
fmt.Println(randStr) //035172
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="RandNumeralOrLetter">RandNumeralOrLetter</span>
|
||||||
|
|
||||||
|
<p>generate a random numeral or letter string</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RandNumeralOrLetter(length int) string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
randStr := random.RandNumeralOrLetter(6)
|
||||||
|
fmt.Println(randStr) //0aW7cQ
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="UUIdV4">UUIdV4</span>
|
### <span id="UUIdV4">UUIdV4</span>
|
||||||
|
|
||||||
<p>Generate a random UUID of version 4 according to RFC 4122.</p>
|
<p>Generate a random UUID of version 4 according to RFC 4122.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -116,6 +227,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func UUIdV4() (string, error)
|
func UUIdV4() (string, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -123,16 +235,40 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/random"
|
"github.com/duke-git/lancet/random"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
uuid, err := random.UUIdV4()
|
uuid, err := random.UUIdV4()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Println(uuid)
|
fmt.Println(uuid)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="RandUniqueIntSlice">RandUniqueIntSlice</span>
|
||||||
|
|
||||||
|
<p>Generate a slice of random int of length n that do not repeat.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RandUniqueIntSlice(n, min, max int) []int
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result := RandUniqueIntSlice(5, 0, 10)
|
||||||
|
fmt.Println(result) //[0 4 7 1 5] (random)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,37 +1,43 @@
|
|||||||
# Random
|
# Random
|
||||||
random随机数生成器包,可以生成随机[]bytes, int, string。
|
|
||||||
|
random 随机数生成器包,可以生成随机[]bytes, int, string。
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<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)
|
[https://github.com/duke-git/lancet/blob/v1/random/random.go](https://github.com/duke-git/lancet/blob/v1/random/random.go)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 用法:
|
## 用法:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/v2/random"
|
"github.com/duke-git/lancet/random"
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 目录
|
## 目录
|
||||||
- [RandBytes](#RandBytes)
|
|
||||||
- [RandInt](#RandInt)
|
|
||||||
- [RandString](#RandString)
|
|
||||||
- [UUIdV4](#UUIdV4)
|
|
||||||
|
|
||||||
|
- [RandBytes](#RandBytes)
|
||||||
|
- [RandInt](#RandInt)
|
||||||
|
- [RandString](#RandString)
|
||||||
|
- [RandUpper](#RandUpper)
|
||||||
|
- [RandLower](#RandLower)
|
||||||
|
- [RandNumeral](#RandNumeral)
|
||||||
|
- [RandNumeralOrLetter](#RandNumeralOrLetter)
|
||||||
|
- [UUIdV4](#UUIdV4)
|
||||||
|
- [RandUniqueIntSlice](#RandUniqueIntSlice)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 文档
|
## 文档
|
||||||
|
|
||||||
|
|
||||||
### <span id="RandBytes">RandBytes</span>
|
### <span id="RandBytes">RandBytes</span>
|
||||||
|
|
||||||
<p>生成随机字节切片</p>
|
<p>生成随机字节切片</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -39,6 +45,7 @@ import (
|
|||||||
```go
|
```go
|
||||||
func RandBytes(length int) []byte
|
func RandBytes(length int) []byte
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -46,17 +53,17 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/random"
|
"github.com/duke-git/lancet/random"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
randBytes := random.RandBytes(4)
|
randBytes := random.RandBytes(4)
|
||||||
fmt.Println(randBytes)
|
fmt.Println(randBytes)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="RandInt">RandInt</span>
|
### <span id="RandInt">RandInt</span>
|
||||||
|
|
||||||
<p>生成随机int, 范围[min, max)</p>
|
<p>生成随机int, 范围[min, max)</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -64,6 +71,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func RandInt(min, max int) int
|
func RandInt(min, max int) int
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -71,25 +79,25 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/random"
|
"github.com/duke-git/lancet/random"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rInt := random.RandInt(1, 10)
|
rInt := random.RandInt(1, 10)
|
||||||
fmt.Println(rInt)
|
fmt.Println(rInt)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="RandString">RandString</span>
|
||||||
|
|
||||||
|
<p>生成给定长度的随机字符串,只包含字母(a-zA-Z)</p>
|
||||||
### <span id="RandString">RandInt</span>
|
|
||||||
<p>生成随机给定长度的随机字符串</p>
|
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func RandString(length int) string
|
func RandString(length int) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -97,18 +105,121 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/random"
|
"github.com/duke-git/lancet/random"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
randStr := random.RandString(6)
|
randStr := random.RandString(6)
|
||||||
fmt.Println(randStr)
|
fmt.Println(randStr) //pGWsze
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="RandUpper">RandUpper</span>
|
||||||
|
|
||||||
|
<p>生成给定长度的随机大写字母字符串</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RandUpper(length int) string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
randStr := random.RandString(6)
|
||||||
|
fmt.Println(randStr) //PACWGF
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="RandLower">RandLower</span>
|
||||||
|
|
||||||
|
<p>生成给定长度的随机小写字母字符串</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RandLower(length int) string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
randStr := random.RandLower(6)
|
||||||
|
fmt.Println(randStr) //siqbew
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="RandNumeral">RandNumeral</span>
|
||||||
|
|
||||||
|
<p>生成给定长度的随机数字字符串</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RandNumeral(length int) string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
randStr := random.RandNumeral(6)
|
||||||
|
fmt.Println(randStr) //035172
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="RandNumeralOrLetter">RandNumeralOrLetter</span>
|
||||||
|
|
||||||
|
<p>生成给定长度的随机字符串(数字+字母)</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RandNumeralOrLetter(length int) string
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
randStr := random.RandNumeralOrLetter(6)
|
||||||
|
fmt.Println(randStr) //0aW7cQ
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="UUIdV4">UUIdV4</span>
|
### <span id="UUIdV4">UUIdV4</span>
|
||||||
|
|
||||||
<p>生成UUID v4字符串</p>
|
<p>生成UUID v4字符串</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -116,6 +227,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func UUIdV4() (string, error)
|
func UUIdV4() (string, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -123,16 +235,40 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/random"
|
"github.com/duke-git/lancet/random"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
uuid, err := random.UUIdV4()
|
uuid, err := random.UUIdV4()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Println(uuid)
|
fmt.Println(uuid)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="RandUniqueIntSlice">RandUniqueIntSlice</span>
|
||||||
|
|
||||||
|
<p>生成一个不重复的长度为n的随机int切片。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RandUniqueIntSlice(n, min, max int) []int
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result := RandUniqueIntSlice(5, 0, 10)
|
||||||
|
fmt.Println(result) //[0 4 7 1 5] (random)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
167
docs/retry.md
167
docs/retry.md
@@ -1,37 +1,39 @@
|
|||||||
# Retry
|
# Retry
|
||||||
|
|
||||||
Package retry is for executing a function repeatedly until it was successful or canceled by the context.
|
Package retry is for executing a function repeatedly until it was successful or canceled by the context.
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Source:
|
## Source:
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/retry/retry.go](https://github.com/duke-git/lancet/blob/main/retry/retry.go)
|
[https://github.com/duke-git/lancet/blob/v1/retry/retry.go](https://github.com/duke-git/lancet/blob/v1/retry/retry.go)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Usage:
|
## Usage:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/v2/retry"
|
"github.com/duke-git/lancet/retry"
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Index
|
## Index
|
||||||
- [Context](#Context)
|
|
||||||
- [Retry](#Retry)
|
- [Context](#Context)
|
||||||
- [RetryFunc](#RetryFunc)
|
- [Retry](#Retry)
|
||||||
- [RetryDuration](#RetryDuration)
|
- [RetryFunc](#RetryFunc)
|
||||||
- [RetryTimes](#RetryTimes)
|
- [RetryDuration](#RetryDuration)
|
||||||
|
- [RetryTimes](#RetryTimes)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
|
||||||
### <span id="Context">Context</span>
|
### <span id="Context">Context</span>
|
||||||
|
|
||||||
<p>Set retry context config, can cancel the retry with context.</p>
|
<p>Set retry context config, can cancel the retry with context.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -39,43 +41,42 @@ import (
|
|||||||
```go
|
```go
|
||||||
func Context(ctx context.Context)
|
func Context(ctx context.Context)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/retry"
|
"github.com/duke-git/lancet/retry"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
ctx, cancel := context.WithCancel(context.TODO())
|
ctx, cancel := context.WithCancel(context.TODO())
|
||||||
var number int
|
var number int
|
||||||
increaseNumber := func() error {
|
increaseNumber := func() error {
|
||||||
number++
|
number++
|
||||||
if number > 3 {
|
if number > 3 {
|
||||||
cancel()
|
cancel()
|
||||||
}
|
}
|
||||||
return errors.New("error occurs")
|
return errors.New("error occurs")
|
||||||
}
|
}
|
||||||
|
|
||||||
err := retry.Retry(increaseNumber,
|
err := retry.Retry(increaseNumber,
|
||||||
retry.RetryDuration(time.Microsecond*50),
|
retry.RetryDuration(time.Microsecond*50),
|
||||||
retry.Context(ctx),
|
retry.Context(ctx),
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err) //retry is cancelled
|
fmt.Println(err) //retry is cancelled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="RetryFunc">RetryFunc</span>
|
### <span id="RetryFunc">RetryFunc</span>
|
||||||
|
|
||||||
<p>Function that retry executes.</p>
|
<p>Function that retry executes.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -83,6 +84,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
type RetryFunc func() error
|
type RetryFunc func() error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -92,32 +94,31 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"github.com/duke-git/lancet/v2/retry"
|
"github.com/duke-git/lancet/retry"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var number int
|
var number int
|
||||||
var increaseNumber retry.RetryFunc
|
var increaseNumber retry.RetryFunc
|
||||||
increaseNumber = func() error {
|
increaseNumber = func() error {
|
||||||
number++
|
number++
|
||||||
if number == 3 {
|
if number == 3 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return errors.New("error occurs")
|
return errors.New("error occurs")
|
||||||
}
|
}
|
||||||
|
|
||||||
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(number) //3
|
fmt.Println(number) //3
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="RetryTimes">RetryTimes</span>
|
### <span id="RetryTimes">RetryTimes</span>
|
||||||
|
|
||||||
<p>Set times of retry. Default times is 5.</p>
|
<p>Set times of retry. Default times is 5.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -125,6 +126,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func RetryTimes(n uint)
|
func RetryTimes(n uint)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -134,29 +136,28 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"github.com/duke-git/lancet/v2/retry"
|
"github.com/duke-git/lancet/retry"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var number int
|
var number int
|
||||||
increaseNumber := func() error {
|
increaseNumber := func() error {
|
||||||
number++
|
number++
|
||||||
if number == 3 {
|
if number == 3 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return errors.New("error occurs")
|
return errors.New("error occurs")
|
||||||
}
|
}
|
||||||
|
|
||||||
err := retry.Retry(increaseNumber, retry.RetryTimes(2))
|
err := retry.Retry(increaseNumber, retry.RetryTimes(2))
|
||||||
if err != nil {
|
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
|
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>
|
### <span id="RetryDuration">RetryDuration</span>
|
||||||
|
|
||||||
<p>Set duration of retries. Default duration is 3 second.</p>
|
<p>Set duration of retries. Default duration is 3 second.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -164,6 +165,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func RetryDuration(d time.Duration)
|
func RetryDuration(d time.Duration)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -173,30 +175,30 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"github.com/duke-git/lancet/v2/retry"
|
"github.com/duke-git/lancet/retry"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var number int
|
var number int
|
||||||
increaseNumber := func() error {
|
increaseNumber := func() error {
|
||||||
number++
|
number++
|
||||||
if number == 3 {
|
if number == 3 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return errors.New("error occurs")
|
return errors.New("error occurs")
|
||||||
}
|
}
|
||||||
|
|
||||||
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(number) //3
|
fmt.Println(number) //3
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="Retry">Retry</span>
|
### <span id="Retry">Retry</span>
|
||||||
|
|
||||||
<p>Executes the retryFunc repeatedly until it was successful or canceled by the context.</p>
|
<p>Executes the retryFunc repeatedly until it was successful or canceled by the context.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -204,6 +206,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Retry(retryFunc RetryFunc, opts ...Option) error
|
func Retry(retryFunc RetryFunc, opts ...Option) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -213,23 +216,23 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"github.com/duke-git/lancet/v2/retry"
|
"github.com/duke-git/lancet/retry"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var number int
|
var number int
|
||||||
increaseNumber := func() error {
|
increaseNumber := func() error {
|
||||||
number++
|
number++
|
||||||
if number == 3 {
|
if number == 3 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return errors.New("error occurs")
|
return errors.New("error occurs")
|
||||||
}
|
}
|
||||||
|
|
||||||
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(number) //3
|
fmt.Println(number) //3
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +1,39 @@
|
|||||||
# Retry
|
# Retry
|
||||||
retry重试执行函数直到函数运行成功或被context cancel。
|
|
||||||
|
retry 重试执行函数直到函数运行成功或被 context cancel。
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 源码:
|
## 源码:
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/retry/retry.go](https://github.com/duke-git/lancet/blob/main/retry/retry.go)
|
[https://github.com/duke-git/lancet/blob/v1/retry/retry.go](https://github.com/duke-git/lancet/blob/v1/retry/retry.go)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 用法:
|
## 用法:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/v2/retry"
|
"github.com/duke-git/lancet/retry"
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 目录
|
## 目录
|
||||||
- [Context](#Context)
|
|
||||||
- [Retry](#Retry)
|
|
||||||
- [RetryFunc](#RetryFunc)
|
|
||||||
- [RetryDuration](#RetryDuration)
|
|
||||||
- [RetryTimes](#RetryTimes)
|
|
||||||
|
|
||||||
|
- [Context](#Context)
|
||||||
|
- [Retry](#Retry)
|
||||||
|
- [RetryFunc](#RetryFunc)
|
||||||
|
- [RetryDuration](#RetryDuration)
|
||||||
|
- [RetryTimes](#RetryTimes)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
## Document 文档
|
||||||
## Document文档
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="Context">Context</span>
|
### <span id="Context">Context</span>
|
||||||
|
|
||||||
<p>设置重试context参数</p>
|
<p>设置重试context参数</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -41,43 +41,42 @@ import (
|
|||||||
```go
|
```go
|
||||||
func Context(ctx context.Context)
|
func Context(ctx context.Context)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"lancet-demo/retry"
|
"lancet-demo/retry"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
ctx, cancel := context.WithCancel(context.TODO())
|
ctx, cancel := context.WithCancel(context.TODO())
|
||||||
var number int
|
var number int
|
||||||
increaseNumber := func() error {
|
increaseNumber := func() error {
|
||||||
number++
|
number++
|
||||||
if number > 3 {
|
if number > 3 {
|
||||||
cancel()
|
cancel()
|
||||||
}
|
}
|
||||||
return errors.New("error occurs")
|
return errors.New("error occurs")
|
||||||
}
|
}
|
||||||
|
|
||||||
err := retry.Retry(increaseNumber,
|
err := retry.Retry(increaseNumber,
|
||||||
retry.RetryDuration(time.Microsecond*50),
|
retry.RetryDuration(time.Microsecond*50),
|
||||||
retry.Context(ctx),
|
retry.Context(ctx),
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err) //retry is cancelled
|
fmt.Println(err) //retry is cancelled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="RetryFunc">RetryFunc</span>
|
### <span id="RetryFunc">RetryFunc</span>
|
||||||
|
|
||||||
<p>被重试执行的函数</p>
|
<p>被重试执行的函数</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -85,6 +84,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
type RetryFunc func() error
|
type RetryFunc func() error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -94,32 +94,31 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"github.com/duke-git/lancet/v2/retry"
|
"github.com/duke-git/lancet/retry"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var number int
|
var number int
|
||||||
var increaseNumber retry.RetryFunc
|
var increaseNumber retry.RetryFunc
|
||||||
increaseNumber = func() error {
|
increaseNumber = func() error {
|
||||||
number++
|
number++
|
||||||
if number == 3 {
|
if number == 3 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return errors.New("error occurs")
|
return errors.New("error occurs")
|
||||||
}
|
}
|
||||||
|
|
||||||
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(number) //3
|
fmt.Println(number) //3
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="RetryTimes">RetryTimes</span>
|
### <span id="RetryTimes">RetryTimes</span>
|
||||||
|
|
||||||
<p>设置重试次数,默认5</p>
|
<p>设置重试次数,默认5</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -127,6 +126,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func RetryTimes(n uint)
|
func RetryTimes(n uint)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -136,29 +136,28 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"github.com/duke-git/lancet/v2/retry"
|
"github.com/duke-git/lancet/retry"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var number int
|
var number int
|
||||||
increaseNumber := func() error {
|
increaseNumber := func() error {
|
||||||
number++
|
number++
|
||||||
if number == 3 {
|
if number == 3 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return errors.New("error occurs")
|
return errors.New("error occurs")
|
||||||
}
|
}
|
||||||
|
|
||||||
err := retry.Retry(increaseNumber, retry.RetryTimes(2))
|
err := retry.Retry(increaseNumber, retry.RetryTimes(2))
|
||||||
if err != nil {
|
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
|
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>
|
### <span id="RetryDuration">RetryDuration</span>
|
||||||
|
|
||||||
<p>设置重试间隔时间,默认3秒</p>
|
<p>设置重试间隔时间,默认3秒</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -166,6 +165,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func RetryDuration(d time.Duration)
|
func RetryDuration(d time.Duration)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -175,30 +175,30 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"github.com/duke-git/lancet/v2/retry"
|
"github.com/duke-git/lancet/retry"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var number int
|
var number int
|
||||||
increaseNumber := func() error {
|
increaseNumber := func() error {
|
||||||
number++
|
number++
|
||||||
if number == 3 {
|
if number == 3 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return errors.New("error occurs")
|
return errors.New("error occurs")
|
||||||
}
|
}
|
||||||
|
|
||||||
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(number) //3
|
fmt.Println(number) //3
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="Retry">Retry</span>
|
### <span id="Retry">Retry</span>
|
||||||
|
|
||||||
<p>重试执行函数retryFunc,直到函数运行成功,或被context停止</p>
|
<p>重试执行函数retryFunc,直到函数运行成功,或被context停止</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
@@ -206,6 +206,7 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func Retry(retryFunc RetryFunc, opts ...Option) error
|
func Retry(retryFunc RetryFunc, opts ...Option) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>例子:</b>
|
<b>例子:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -215,23 +216,23 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"github.com/duke-git/lancet/v2/retry"
|
"github.com/duke-git/lancet/retry"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var number int
|
var number int
|
||||||
increaseNumber := func() error {
|
increaseNumber := func() error {
|
||||||
number++
|
number++
|
||||||
if number == 3 {
|
if number == 3 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return errors.New("error occurs")
|
return errors.New("error occurs")
|
||||||
}
|
}
|
||||||
|
|
||||||
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(number) //3
|
fmt.Println(number) //3
|
||||||
}
|
}
|
||||||
|
|||||||
1029
docs/slice.md
1029
docs/slice.md
File diff suppressed because it is too large
Load Diff
1028
docs/slice_zh-CN.md
1028
docs/slice_zh-CN.md
File diff suppressed because it is too large
Load Diff
1122
docs/strutil.md
1122
docs/strutil.md
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
157
docs/system.md
157
docs/system.md
@@ -1,41 +1,43 @@
|
|||||||
# System
|
# System
|
||||||
|
|
||||||
Package system contains some functions about os, runtime, shell command.
|
Package system contains some functions about os, runtime, shell command.
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Source:
|
## Source:
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/system/os.go](https://github.com/duke-git/lancet/blob/main/system/os.go)
|
[https://github.com/duke-git/lancet/blob/v1/system/os.go](https://github.com/duke-git/lancet/blob/v1/system/os.go)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Usage:
|
## Usage:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/v2/system"
|
"github.com/duke-git/lancet/system"
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Index
|
## Index
|
||||||
- [IsWindows](#IsWindows)
|
|
||||||
- [IsLinux](#IsLinux)
|
- [IsWindows](#IsWindows)
|
||||||
- [IsMac](#IsMac)
|
- [IsLinux](#IsLinux)
|
||||||
- [GetOsEnv](#GetOsEnv)
|
- [IsMac](#IsMac)
|
||||||
- [SetOsEnv](#SetOsEnv)
|
- [GetOsEnv](#GetOsEnv)
|
||||||
- [RemoveOsEnv](#RemoveOsEnv)
|
- [SetOsEnv](#SetOsEnv)
|
||||||
- [CompareOsEnv](#CompareOsEnv)
|
- [RemoveOsEnv](#RemoveOsEnv)
|
||||||
- [ExecCommand](#ExecCommand)
|
- [CompareOsEnv](#CompareOsEnv)
|
||||||
|
- [ExecCommand](#ExecCommand)
|
||||||
|
- [GetOsBits](#GetOsBits)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
|
||||||
### <span id="IsWindows">IsWindows</span>
|
### <span id="IsWindows">IsWindows</span>
|
||||||
|
|
||||||
<p>Check if current os is windows.</p>
|
<p>Check if current os is windows.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -43,24 +45,23 @@ import (
|
|||||||
```go
|
```go
|
||||||
func IsWindows() bool
|
func IsWindows() bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/system"
|
"github.com/duke-git/lancet/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
isOsWindows := system.IsWindows()
|
isOsWindows := system.IsWindows()
|
||||||
fmt.Println(isOsWindows)
|
fmt.Println(isOsWindows)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="IsLinux">IsLinux</span>
|
### <span id="IsLinux">IsLinux</span>
|
||||||
|
|
||||||
<p>Check if current os is linux.</p>
|
<p>Check if current os is linux.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -68,23 +69,23 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func IsLinux() bool
|
func IsLinux() bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/system"
|
"github.com/duke-git/lancet/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
isOsLinux := system.IsLinux()
|
isOsLinux := system.IsLinux()
|
||||||
fmt.Println(isOsLinux)
|
fmt.Println(isOsLinux)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="IsMac">IsMac</span>
|
### <span id="IsMac">IsMac</span>
|
||||||
|
|
||||||
<p>Check if current os is macos.</p>
|
<p>Check if current os is macos.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -92,23 +93,23 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func IsMac() bool
|
func IsMac() bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/system"
|
"github.com/duke-git/lancet/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
isOsMac := system.IsMac
|
isOsMac := system.IsMac
|
||||||
fmt.Println(isOsMac)
|
fmt.Println(isOsMac)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="GetOsEnv">GetOsEnv</span>
|
### <span id="GetOsEnv">GetOsEnv</span>
|
||||||
|
|
||||||
<p>Gets the value of the environment variable named by the key.</p>
|
<p>Gets the value of the environment variable named by the key.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -116,23 +117,23 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func GetOsEnv(key string) string
|
func GetOsEnv(key string) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/system"
|
"github.com/duke-git/lancet/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fooEnv := system.GetOsEnv("foo")
|
fooEnv := system.GetOsEnv("foo")
|
||||||
fmt.Println(fooEnv)
|
fmt.Println(fooEnv)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="SetOsEnv">SetOsEnv</span>
|
### <span id="SetOsEnv">SetOsEnv</span>
|
||||||
|
|
||||||
<p>Sets the value of the environment variable named by the key.</p>
|
<p>Sets the value of the environment variable named by the key.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -140,24 +141,23 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func SetOsEnv(key, value string) error
|
func SetOsEnv(key, value string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/system"
|
"github.com/duke-git/lancet/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := system.SetOsEnv("foo", "foo_value")
|
err := system.SetOsEnv("foo", "foo_value")
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="RemoveOsEnv">RemoveOsEnv</span>
|
### <span id="RemoveOsEnv">RemoveOsEnv</span>
|
||||||
|
|
||||||
<p>Remove a single environment variable.</p>
|
<p>Remove a single environment variable.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -165,25 +165,25 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func RemoveOsEnv(key string) error
|
func RemoveOsEnv(key string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/system"
|
"github.com/duke-git/lancet/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := system.RemoveOsEnv("foo")
|
err := system.RemoveOsEnv("foo")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="CompareOsEnv">CompareOsEnv</span>
|
### <span id="CompareOsEnv">CompareOsEnv</span>
|
||||||
|
|
||||||
<p>Get env named by the key and compare it with comparedEnv.</p>
|
<p>Get env named by the key and compare it with comparedEnv.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -191,52 +191,71 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func CompareOsEnv(key, comparedEnv string) bool
|
func CompareOsEnv(key, comparedEnv string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/system"
|
"github.com/duke-git/lancet/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
system.SetOsEnv("foo", "foo_value")
|
system.SetOsEnv("foo", "foo_value")
|
||||||
res := system.CompareOsEnv("foo", "foo_value")
|
res := system.CompareOsEnv("foo", "foo_value")
|
||||||
fmt.Println(res) //true
|
fmt.Println(res) //true
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="ExecCommand">ExecCommand</span>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ExecCommand">CompareOsEnv</span>
|
|
||||||
<p>use shell /bin/bash -c(linux) or cmd (windows) to execute command.</p>
|
<p>use shell /bin/bash -c(linux) or cmd (windows) to execute command.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func ExecCommand(command string) (stdout, stderr string, err error)
|
type (
|
||||||
|
Option func(*exec.Cmd)
|
||||||
|
)
|
||||||
|
func ExecCommand(command string, opts ...Option) (stdout, stderr string, err error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/system"
|
"github.com/duke-git/lancet/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
out, errout, err := system.ExecCommand("ls")
|
out, errout, err := system.ExecCommand("ls", system.WithForeground())
|
||||||
fmt.Println(out)
|
fmt.Println(out)
|
||||||
fmt.Println(errout)
|
fmt.Println(errout)
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="GetOsBits">GetOsBits</span>
|
||||||
|
|
||||||
|
<p>获取当前操作系统位数,返回32或64</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GetOsBits() int
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/system"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
osBit := system.GetOsBits()
|
||||||
|
fmt.Println(osBit)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,41 +1,43 @@
|
|||||||
# System
|
# System
|
||||||
system包含os, runtime, shell command相关函数。
|
|
||||||
|
system 包含 os, runtime, shell command 相关函数。
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 源码:
|
## 源码:
|
||||||
|
|
||||||
- [https://github.com/duke-git/lancet/blob/main/system/os.go](https://github.com/duke-git/lancet/blob/main/system/os.go)
|
[https://github.com/duke-git/lancet/blob/v1/system/os.go](https://github.com/duke-git/lancet/blob/v1/system/os.go)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 用法:
|
## 用法:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/v2/system"
|
"github.com/duke-git/lancet/system"
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## 目录
|
## 目录
|
||||||
- [IsWindows](#IsWindows)
|
|
||||||
- [IsLinux](#IsLinux)
|
- [IsWindows](#IsWindows)
|
||||||
- [IsMac](#IsMac)
|
- [IsLinux](#IsLinux)
|
||||||
- [GetOsEnv](#GetOsEnv)
|
- [IsMac](#IsMac)
|
||||||
- [SetOsEnv](#SetOsEnv)
|
- [GetOsEnv](#GetOsEnv)
|
||||||
- [RemoveOsEnv](#RemoveOsEnv)
|
- [SetOsEnv](#SetOsEnv)
|
||||||
- [CompareOsEnv](#CompareOsEnv)
|
- [RemoveOsEnv](#RemoveOsEnv)
|
||||||
- [ExecCommand](#ExecCommand)
|
- [CompareOsEnv](#CompareOsEnv)
|
||||||
|
- [ExecCommand](#ExecCommand)
|
||||||
|
- [GetOsBits](#GetOsBits)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
## Documentation文档
|
## Documentation 文档
|
||||||
|
|
||||||
|
|
||||||
### <span id="IsWindows">IsWindows</span>
|
### <span id="IsWindows">IsWindows</span>
|
||||||
|
|
||||||
<p>检查当前操作系统是否是windows</p>
|
<p>检查当前操作系统是否是windows</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -43,24 +45,23 @@ import (
|
|||||||
```go
|
```go
|
||||||
func IsWindows() bool
|
func IsWindows() bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/system"
|
"github.com/duke-git/lancet/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
isOsWindows := system.IsWindows()
|
isOsWindows := system.IsWindows()
|
||||||
fmt.Println(isOsWindows)
|
fmt.Println(isOsWindows)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="IsLinux">IsLinux</span>
|
### <span id="IsLinux">IsLinux</span>
|
||||||
|
|
||||||
<p>检查当前操作系统是否是linux</p>
|
<p>检查当前操作系统是否是linux</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -68,23 +69,23 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func IsLinux() bool
|
func IsLinux() bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/system"
|
"github.com/duke-git/lancet/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
isOsLinux := system.IsLinux()
|
isOsLinux := system.IsLinux()
|
||||||
fmt.Println(isOsLinux)
|
fmt.Println(isOsLinux)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="IsMac">IsMac</span>
|
### <span id="IsMac">IsMac</span>
|
||||||
|
|
||||||
<p>检查当前操作系统是否是macos</p>
|
<p>检查当前操作系统是否是macos</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -92,23 +93,23 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func IsMac() bool
|
func IsMac() bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/system"
|
"github.com/duke-git/lancet/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
isOsMac := system.IsMac
|
isOsMac := system.IsMac
|
||||||
fmt.Println(isOsMac)
|
fmt.Println(isOsMac)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="GetOsEnv">GetOsEnv</span>
|
### <span id="GetOsEnv">GetOsEnv</span>
|
||||||
|
|
||||||
<p>获取key命名的环境变量的值</p>
|
<p>获取key命名的环境变量的值</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -116,23 +117,23 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func GetOsEnv(key string) string
|
func GetOsEnv(key string) string
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/system"
|
"github.com/duke-git/lancet/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fooEnv := system.GetOsEnv("foo")
|
fooEnv := system.GetOsEnv("foo")
|
||||||
fmt.Println(fooEnv)
|
fmt.Println(fooEnv)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="SetOsEnv">SetOsEnv</span>
|
### <span id="SetOsEnv">SetOsEnv</span>
|
||||||
|
|
||||||
<p>设置由key命名的环境变量的值</p>
|
<p>设置由key命名的环境变量的值</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -140,24 +141,23 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func SetOsEnv(key, value string) error
|
func SetOsEnv(key, value string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/system"
|
"github.com/duke-git/lancet/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := system.SetOsEnv("foo", "foo_value")
|
err := system.SetOsEnv("foo", "foo_value")
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="RemoveOsEnv">RemoveOsEnv</span>
|
### <span id="RemoveOsEnv">RemoveOsEnv</span>
|
||||||
|
|
||||||
<p>删除单个环境变量</p>
|
<p>删除单个环境变量</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -165,25 +165,25 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func RemoveOsEnv(key string) error
|
func RemoveOsEnv(key string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/system"
|
"github.com/duke-git/lancet/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := system.RemoveOsEnv("foo")
|
err := system.RemoveOsEnv("foo")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="CompareOsEnv">CompareOsEnv</span>
|
### <span id="CompareOsEnv">CompareOsEnv</span>
|
||||||
|
|
||||||
<p>获取key命名的环境变量值并与compareEnv进行比较</p>
|
<p>获取key命名的环境变量值并与compareEnv进行比较</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -191,52 +191,71 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
func CompareOsEnv(key, comparedEnv string) bool
|
func CompareOsEnv(key, comparedEnv string) bool
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/system"
|
"github.com/duke-git/lancet/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
system.SetOsEnv("foo", "foo_value")
|
system.SetOsEnv("foo", "foo_value")
|
||||||
res := system.CompareOsEnv("foo", "foo_value")
|
res := system.CompareOsEnv("foo", "foo_value")
|
||||||
fmt.Println(res) //true
|
fmt.Println(res) //true
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="ExecCommand">ExecCommand</span>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <span id="ExecCommand">CompareOsEnv</span>
|
|
||||||
<p>使用shell /bin/bash -c(linux) 或 cmd (windows) 执行shell命令</p>
|
<p>使用shell /bin/bash -c(linux) 或 cmd (windows) 执行shell命令</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func ExecCommand(command string) (stdout, stderr string, err error)
|
type (
|
||||||
|
Option func(*exec.Cmd)
|
||||||
|
)
|
||||||
|
func ExecCommand(command string, opts ...Option) (stdout, stderr string, err error)
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/system"
|
"github.com/duke-git/lancet/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
out, errout, err := system.ExecCommand("ls")
|
out, errout, err := system.ExecCommand("ls", system.WithForeground())
|
||||||
fmt.Println(out)
|
fmt.Println(out)
|
||||||
fmt.Println(errout)
|
fmt.Println(errout)
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="GetOsBits">GetOsBits</span>
|
||||||
|
|
||||||
|
<p>Get current os bits, 32bit or 64bit. return 32 or 64</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GetOsBits() int
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/system"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
osBit := system.GetOsBits()
|
||||||
|
fmt.Println(osBit)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,57 +0,0 @@
|
|||||||
# 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"))
|
|
||||||
}
|
|
||||||
```
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
# 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"))
|
|
||||||
}
|
|
||||||
```
|
|
||||||
314
fileutil/file.go
314
fileutil/file.go
@@ -7,13 +7,21 @@ package fileutil
|
|||||||
import (
|
import (
|
||||||
"archive/zip"
|
"archive/zip"
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"crypto/sha1"
|
||||||
|
"crypto/sha256"
|
||||||
|
"crypto/sha512"
|
||||||
|
"encoding/csv"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -40,6 +48,11 @@ func CreateFile(path string) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateDir create directory in absolute path. param `absPath` like /a/, /a/b/
|
||||||
|
func CreateDir(absPath string) error {
|
||||||
|
return os.MkdirAll(path.Dir(absPath), os.ModePerm)
|
||||||
|
}
|
||||||
|
|
||||||
// IsDir checks if the path is directory or not
|
// IsDir checks if the path is directory or not
|
||||||
func IsDir(path string) bool {
|
func IsDir(path string) bool {
|
||||||
file, err := os.Stat(path)
|
file, err := os.Stat(path)
|
||||||
@@ -81,7 +94,7 @@ func CopyFile(srcFilePath string, dstFilePath string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//ClearFile write empty string to path file
|
// ClearFile write empty string to path file
|
||||||
func ClearFile(path string) error {
|
func ClearFile(path string) error {
|
||||||
f, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
|
f, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -93,7 +106,7 @@ func ClearFile(path string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
//ReadFileToString return string of file content
|
// ReadFileToString return string of file content
|
||||||
func ReadFileToString(path string) (string, error) {
|
func ReadFileToString(path string) (string, error) {
|
||||||
bytes, err := ioutil.ReadFile(path)
|
bytes, err := ioutil.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -165,44 +178,7 @@ func Zip(fpath string, destPath string) error {
|
|||||||
archive := zip.NewWriter(zipFile)
|
archive := zip.NewWriter(zipFile)
|
||||||
defer archive.Close()
|
defer archive.Close()
|
||||||
|
|
||||||
filepath.Walk(fpath, func(path string, info os.FileInfo, err error) error {
|
return addFileToArchive(fpath, archive)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
header, err := zip.FileInfoHeader(info)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
header.Name = strings.TrimPrefix(path, filepath.Dir(fpath)+"/")
|
|
||||||
|
|
||||||
if info.IsDir() {
|
|
||||||
header.Name += "/"
|
|
||||||
} else {
|
|
||||||
header.Method = zip.Deflate
|
|
||||||
}
|
|
||||||
|
|
||||||
writer, err := archive.CreateHeader(header)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !info.IsDir() {
|
|
||||||
file, err := os.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
_, err = io.Copy(writer, file)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnZip unzip the file and save it to destPath
|
// UnZip unzip the file and save it to destPath
|
||||||
@@ -214,7 +190,11 @@ func UnZip(zipFile string, destPath string) error {
|
|||||||
defer zipReader.Close()
|
defer zipReader.Close()
|
||||||
|
|
||||||
for _, f := range zipReader.File {
|
for _, f := range zipReader.File {
|
||||||
path := filepath.Join(destPath, f.Name)
|
//issue#62: fix ZipSlip bug
|
||||||
|
path, err := safeFilepathJoin(destPath, f.Name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if f.FileInfo().IsDir() {
|
if f.FileInfo().IsDir() {
|
||||||
os.MkdirAll(path, os.ModePerm)
|
os.MkdirAll(path, os.ModePerm)
|
||||||
} else {
|
} else {
|
||||||
@@ -243,6 +223,110 @@ func UnZip(zipFile string, destPath string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ZipAppendEntry append a single file or directory by fpath to an existing zip file.
|
||||||
|
// Play: https://go.dev/play/p/cxvaT8TRNQp
|
||||||
|
func ZipAppendEntry(fpath string, destPath string) error {
|
||||||
|
tempFile, err := os.CreateTemp("", "temp.zip")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer os.Remove(tempFile.Name())
|
||||||
|
|
||||||
|
zipReader, err := zip.OpenReader(destPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
archive := zip.NewWriter(tempFile)
|
||||||
|
|
||||||
|
for _, zipItem := range zipReader.File {
|
||||||
|
zipItemReader, err := zipItem.Open()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
header, err := zip.FileInfoHeader(zipItem.FileInfo())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
header.Name = zipItem.Name
|
||||||
|
targetItem, err := archive.CreateHeader(header)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = io.Copy(targetItem, zipItemReader)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = addFileToArchive(fpath, archive)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = zipReader.Close()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = archive.Close()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = tempFile.Close()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return CopyFile(tempFile.Name(), destPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func addFileToArchive(fpath string, archive *zip.Writer) error {
|
||||||
|
err := filepath.Walk(fpath, func(path string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
header, err := zip.FileInfoHeader(info)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
header.Name = strings.TrimPrefix(path, filepath.Dir(fpath)+"/")
|
||||||
|
|
||||||
|
if info.IsDir() {
|
||||||
|
header.Name += "/"
|
||||||
|
} else {
|
||||||
|
header.Method = zip.Deflate
|
||||||
|
writer, err := archive.CreateHeader(header)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
if _, err := io.Copy(writer, file); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func safeFilepathJoin(path1, path2 string) (string, error) {
|
||||||
|
relPath, err := filepath.Rel(".", path2)
|
||||||
|
if err != nil || strings.HasPrefix(relPath, "..") {
|
||||||
|
return "", fmt.Errorf("(zipslip) filepath is unsafe %q: %v", path2, err)
|
||||||
|
}
|
||||||
|
if path1 == "" {
|
||||||
|
path1 = "."
|
||||||
|
}
|
||||||
|
return filepath.Join(path1, filepath.Join("/", relPath)), nil
|
||||||
|
}
|
||||||
|
|
||||||
// IsLink checks if a file is symbol link or not
|
// IsLink checks if a file is symbol link or not
|
||||||
func IsLink(path string) bool {
|
func IsLink(path string) bool {
|
||||||
fi, err := os.Lstat(path)
|
fi, err := os.Lstat(path)
|
||||||
@@ -263,7 +347,7 @@ func FileMode(path string) (fs.FileMode, error) {
|
|||||||
|
|
||||||
// MiMeType return file mime type
|
// MiMeType return file mime type
|
||||||
// param `file` should be string(file path) or *os.File
|
// param `file` should be string(file path) or *os.File
|
||||||
func MiMeType(file any) string {
|
func MiMeType(file interface{}) string {
|
||||||
var mediatype string
|
var mediatype string
|
||||||
|
|
||||||
readBuffer := func(f *os.File) ([]byte, error) {
|
readBuffer := func(f *os.File) ([]byte, error) {
|
||||||
@@ -296,3 +380,149 @@ func MiMeType(file any) string {
|
|||||||
}
|
}
|
||||||
return mediatype
|
return mediatype
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CurrentPath return current absolute path.
|
||||||
|
func CurrentPath() string {
|
||||||
|
var absPath string
|
||||||
|
_, filename, _, ok := runtime.Caller(1)
|
||||||
|
if ok {
|
||||||
|
absPath = path.Dir(filename)
|
||||||
|
}
|
||||||
|
|
||||||
|
return absPath
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsZipFile checks if file is zip or not.
|
||||||
|
func IsZipFile(filepath string) bool {
|
||||||
|
f, err := os.Open(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
buf := make([]byte, 4)
|
||||||
|
if n, err := f.Read(buf); err != nil || n < 4 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes.Equal(buf, []byte("PK\x03\x04"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileSize returns file size in bytes.
|
||||||
|
func FileSize(path string) (int64, error) {
|
||||||
|
f, err := os.Stat(path)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return f.Size(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MTime returns file modified time.
|
||||||
|
func MTime(filepath string) (int64, error) {
|
||||||
|
f, err := os.Stat(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return f.ModTime().Unix(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sha returns file sha value, param `shaType` should be 1, 256 or 512.
|
||||||
|
func Sha(filepath string, shaType ...int) (string, error) {
|
||||||
|
file, err := os.Open(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
h := sha1.New()
|
||||||
|
if len(shaType) > 0 {
|
||||||
|
if shaType[0] == 1 {
|
||||||
|
h = sha1.New()
|
||||||
|
} else if shaType[0] == 256 {
|
||||||
|
h = sha256.New()
|
||||||
|
} else if shaType[0] == 512 {
|
||||||
|
h = sha512.New()
|
||||||
|
} else {
|
||||||
|
return "", errors.New("param `shaType` should be 1, 256 or 512.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.Copy(h, file)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
sha := fmt.Sprintf("%x", h.Sum(nil))
|
||||||
|
|
||||||
|
return sha, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadCsvFile read file content into slice.
|
||||||
|
func ReadCsvFile(filepath string) ([][]string, error) {
|
||||||
|
f, err := os.Open(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
csvReader := csv.NewReader(f)
|
||||||
|
records, err := csvReader.ReadAll()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return records, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteCsvFile write content to target csv file.
|
||||||
|
func WriteCsvFile(filepath string, records [][]string, append bool) error {
|
||||||
|
flag := os.O_RDWR | os.O_CREATE
|
||||||
|
|
||||||
|
if append {
|
||||||
|
flag = flag | os.O_APPEND
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := os.OpenFile(filepath, flag, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
writer := csv.NewWriter(f)
|
||||||
|
writer.Comma = ','
|
||||||
|
|
||||||
|
return writer.WriteAll(records)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteStringToFile write string to target file.
|
||||||
|
func WriteStringToFile(filepath string, content string, append bool) error {
|
||||||
|
flag := os.O_RDWR | os.O_CREATE
|
||||||
|
if append {
|
||||||
|
flag = flag | os.O_APPEND
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := os.OpenFile(filepath, flag, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
_, err = f.WriteString(content)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteBytesToFile write bytes to target file.
|
||||||
|
func WriteBytesToFile(filepath string, content []byte) error {
|
||||||
|
f, err := os.OpenFile(filepath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
_, err = f.Write(content)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/duke-git/lancet/v2/internal"
|
"github.com/duke-git/lancet/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestIsExist(t *testing.T) {
|
func TestIsExist(t *testing.T) {
|
||||||
@@ -33,6 +33,27 @@ func TestCreateFile(t *testing.T) {
|
|||||||
os.Remove(f)
|
os.Remove(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCreateDir(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestCreateDir")
|
||||||
|
|
||||||
|
pwd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
dirPath := pwd + "/a/"
|
||||||
|
err = CreateDir(dirPath)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(true, IsExist(dirPath))
|
||||||
|
os.Remove(dirPath)
|
||||||
|
assert.Equal(false, IsExist(dirPath))
|
||||||
|
}
|
||||||
|
|
||||||
func TestIsDir(t *testing.T) {
|
func TestIsDir(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestIsDir")
|
assert := internal.NewAssert(t, "TestIsDir")
|
||||||
|
|
||||||
@@ -76,10 +97,10 @@ func TestCopyFile(t *testing.T) {
|
|||||||
func TestListFileNames(t *testing.T) {
|
func TestListFileNames(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestListFileNames")
|
assert := internal.NewAssert(t, "TestListFileNames")
|
||||||
|
|
||||||
filesInPath, err := ListFileNames("./")
|
filesInPath, err := ListFileNames("../datetime/")
|
||||||
assert.IsNil(err)
|
assert.IsNil(err)
|
||||||
|
|
||||||
expected := []string{"file.go", "file_test.go"}
|
expected := []string{"conversion.go", "conversion_test.go", "datetime.go", "datetime_test.go"}
|
||||||
assert.Equal(expected, filesInPath)
|
assert.Equal(expected, filesInPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,6 +182,44 @@ func TestZipAndUnZip(t *testing.T) {
|
|||||||
os.RemoveAll(unZipPath)
|
os.RemoveAll(unZipPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestZipAppendEntry(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestZipAppendEntry")
|
||||||
|
|
||||||
|
zipFile := "./text.zip"
|
||||||
|
err := CopyFile("./testdata/file.go.zip", zipFile)
|
||||||
|
assert.IsNil(err)
|
||||||
|
|
||||||
|
srcFile := "./text.txt"
|
||||||
|
CreateFile(srcFile)
|
||||||
|
|
||||||
|
file, _ := os.OpenFile(srcFile, os.O_WRONLY|os.O_TRUNC, os.ModePerm)
|
||||||
|
|
||||||
|
_, err = file.WriteString("hello\nworld")
|
||||||
|
if err != nil {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
file.Close()
|
||||||
|
|
||||||
|
err = ZipAppendEntry(srcFile, zipFile)
|
||||||
|
assert.IsNil(err)
|
||||||
|
|
||||||
|
err = ZipAppendEntry("./testdata", zipFile)
|
||||||
|
assert.IsNil(err)
|
||||||
|
|
||||||
|
unZipPath := "./unzip"
|
||||||
|
err = UnZip(zipFile, unZipPath)
|
||||||
|
assert.IsNil(err)
|
||||||
|
|
||||||
|
assert.Equal(true, IsExist("./unzip/text.txt"))
|
||||||
|
assert.Equal(true, IsExist("./unzip/file.go"))
|
||||||
|
assert.Equal(true, IsExist("./unzip/testdata/file.go.zip"))
|
||||||
|
assert.Equal(true, IsExist("./unzip/testdata/test.txt"))
|
||||||
|
|
||||||
|
os.Remove(srcFile)
|
||||||
|
os.Remove(zipFile)
|
||||||
|
os.RemoveAll(unZipPath)
|
||||||
|
}
|
||||||
|
|
||||||
func TestFileMode(t *testing.T) {
|
func TestFileMode(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestFileMode")
|
assert := internal.NewAssert(t, "TestFileMode")
|
||||||
|
|
||||||
@@ -200,3 +259,145 @@ func TestMiMeType(t *testing.T) {
|
|||||||
assert.Equal("text/plain; charset=utf-8", MiMeType(f))
|
assert.Equal("text/plain; charset=utf-8", MiMeType(f))
|
||||||
assert.Equal("text/plain; charset=utf-8", MiMeType("./file.go"))
|
assert.Equal("text/plain; charset=utf-8", MiMeType("./file.go"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCurrentPath(t *testing.T) {
|
||||||
|
absPath := CurrentPath()
|
||||||
|
t.Log(absPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsZipFile(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestIsZipFile")
|
||||||
|
|
||||||
|
assert.Equal(false, IsZipFile("./file.go"))
|
||||||
|
assert.Equal(true, IsZipFile("./testdata/file.go.zip"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFileSize(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestFileSize")
|
||||||
|
|
||||||
|
size, err := FileSize("./testdata/test.txt")
|
||||||
|
|
||||||
|
assert.IsNil(err)
|
||||||
|
assert.Equal(int64(20), size)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMTime(t *testing.T) {
|
||||||
|
// assert := internal.NewAssert(t, "TestMTime")
|
||||||
|
|
||||||
|
// mtime, err := MTime("./testdata/test.txt")
|
||||||
|
|
||||||
|
// assert.IsNil(err)
|
||||||
|
// assert.Equal(int64(1682478195), mtime)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSha(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestSha")
|
||||||
|
|
||||||
|
sha1, err := Sha("./testdata/test.txt", 1)
|
||||||
|
sha256, err := Sha("./testdata/test.txt", 256)
|
||||||
|
sha512, err := Sha("./testdata/test.txt", 512)
|
||||||
|
|
||||||
|
assert.IsNil(err)
|
||||||
|
assert.Equal("dda3cf10c5a6ff6c6659a497bf7261b287af2bc7", sha1)
|
||||||
|
assert.Equal("aa6d0a3fbc3442c228d606da09e0c1dc98c69a1cac3da1909199e0266171df35", sha256)
|
||||||
|
assert.Equal("d22aba2a1b7a2e2f512756255cc1c3708905646920cb1eb95e45b531ba74774dbbb89baebf1f716220eb9cf4908f1cfc5b2a01267704d9a59f59d77cab609870", sha512)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadCsvFile(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestReadCsvFile")
|
||||||
|
|
||||||
|
content, err := ReadCsvFile("./testdata/demo.csv")
|
||||||
|
t.Log(content)
|
||||||
|
|
||||||
|
assert.IsNil(err)
|
||||||
|
|
||||||
|
assert.Equal(3, len(content))
|
||||||
|
assert.Equal(3, len(content[0]))
|
||||||
|
assert.Equal("Bob", content[0][0])
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteCsvFile(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestWriteCsvFile")
|
||||||
|
|
||||||
|
csvFilePath := "./testdata/test1.csv"
|
||||||
|
content := [][]string{
|
||||||
|
{"Lili", "22", "female"},
|
||||||
|
{"Jim", "21", "male"},
|
||||||
|
}
|
||||||
|
|
||||||
|
err := WriteCsvFile(csvFilePath, content, false)
|
||||||
|
assert.IsNil(err)
|
||||||
|
|
||||||
|
readContent, err := ReadCsvFile(csvFilePath)
|
||||||
|
|
||||||
|
assert.IsNil(err)
|
||||||
|
|
||||||
|
assert.Equal(2, len(readContent))
|
||||||
|
assert.Equal(3, len(readContent[0]))
|
||||||
|
assert.Equal("Lili", content[0][0])
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteStringToFile(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestWriteStringToFile")
|
||||||
|
|
||||||
|
filepath := "./test.txt"
|
||||||
|
|
||||||
|
file, err := os.Create(filepath)
|
||||||
|
if err != nil {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
err = WriteStringToFile(filepath, "hello", false)
|
||||||
|
if err != nil {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
content1, err := ReadFileToString(filepath)
|
||||||
|
if err != nil {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
err = WriteStringToFile(filepath, " world", true)
|
||||||
|
if err != nil {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
content2, err := os.ReadFile(filepath)
|
||||||
|
if err != nil {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal("hello", content1)
|
||||||
|
assert.Equal("hello world", string(content2))
|
||||||
|
|
||||||
|
os.Remove(filepath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteBytesToFile(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestWriteBytesToFile")
|
||||||
|
|
||||||
|
filepath := "./bytes.txt"
|
||||||
|
|
||||||
|
file, err := os.Create(filepath)
|
||||||
|
if err != nil {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
err = WriteBytesToFile(filepath, []byte("hello"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
content, err := os.ReadFile(filepath)
|
||||||
|
if err != nil {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal("hello", string(content))
|
||||||
|
|
||||||
|
os.Remove(filepath)
|
||||||
|
}
|
||||||
|
|||||||
3
fileutil/testdata/demo.csv
vendored
Normal file
3
fileutil/testdata/demo.csv
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Bob, 12, male
|
||||||
|
Duke, 14, male
|
||||||
|
Lucy, 16, female
|
||||||
|
BIN
fileutil/testdata/file.go.zip
vendored
Normal file
BIN
fileutil/testdata/file.go.zip
vendored
Normal file
Binary file not shown.
1
fileutil/testdata/test.txt
vendored
Normal file
1
fileutil/testdata/test.txt
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
this is a test file.
|
||||||
2
fileutil/testdata/test1.csv
vendored
Normal file
2
fileutil/testdata/test1.csv
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
Lili,22,female
|
||||||
|
Jim,21,male
|
||||||
|
@@ -4,14 +4,176 @@
|
|||||||
// Package formatter implements some functions to format string, struct.
|
// Package formatter implements some functions to format string, struct.
|
||||||
package formatter
|
package formatter
|
||||||
|
|
||||||
import "strings"
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
|
||||||
// Comma add comma to number by every 3 numbers from right. ahead by symbol char
|
"github.com/duke-git/lancet/convertor"
|
||||||
func Comma(v any, symbol string) string {
|
"github.com/duke-git/lancet/strutil"
|
||||||
s := numString(v)
|
"github.com/duke-git/lancet/validator"
|
||||||
dotIndex := strings.Index(s, ".")
|
)
|
||||||
if dotIndex != -1 {
|
|
||||||
return symbol + commaString(s[:dotIndex]) + s[dotIndex:]
|
// Comma add comma to a number value by every 3 numbers from right. ahead by symbol char.
|
||||||
|
// if value is invalid number string eg "aa", return empty string
|
||||||
|
// Comma("12345", "$") => "$12,345", Comma(12345, "$") => "$12,345"
|
||||||
|
func Comma(value interface{}, symbol string) string {
|
||||||
|
if validator.IsInt(value) {
|
||||||
|
v, err := convertor.ToInt(value)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return symbol + commaInt(v)
|
||||||
}
|
}
|
||||||
return symbol + commaString(s)
|
|
||||||
|
if validator.IsFloat(value) {
|
||||||
|
v, err := convertor.ToFloat(value)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return symbol + commaFloat(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
if strutil.IsString(value) {
|
||||||
|
v := fmt.Sprintf("%v", value)
|
||||||
|
if validator.IsNumberStr(v) {
|
||||||
|
return symbol + commaStr(v)
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pretty data to JSON string.
|
||||||
|
func Pretty(v interface{}) (string, error) {
|
||||||
|
out, err := json.MarshalIndent(v, "", " ")
|
||||||
|
return string(out), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrettyToWriter pretty encode data to writer.
|
||||||
|
func PrettyToWriter(v interface{}, out io.Writer) error {
|
||||||
|
enc := json.NewEncoder(out)
|
||||||
|
enc.SetIndent("", " ")
|
||||||
|
|
||||||
|
if err := enc.Encode(v); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://en.wikipedia.org/wiki/Binary_prefix
|
||||||
|
const (
|
||||||
|
// Decimal
|
||||||
|
UnitB = 1
|
||||||
|
UnitKB = 1000
|
||||||
|
UnitMB = 1000 * UnitKB
|
||||||
|
UnitGB = 1000 * UnitMB
|
||||||
|
UnitTB = 1000 * UnitGB
|
||||||
|
UnitPB = 1000 * UnitTB
|
||||||
|
UnitEB = 1000 * UnitPB
|
||||||
|
|
||||||
|
// Binary
|
||||||
|
UnitBiB = 1
|
||||||
|
UnitKiB = 1024
|
||||||
|
UnitMiB = 1024 * UnitKiB
|
||||||
|
UnitGiB = 1024 * UnitMiB
|
||||||
|
UnitTiB = 1024 * UnitGiB
|
||||||
|
UnitPiB = 1024 * UnitTiB
|
||||||
|
UnitEiB = 1024 * UnitPiB
|
||||||
|
)
|
||||||
|
|
||||||
|
// type byteUnitMap map[byte]int64
|
||||||
|
|
||||||
|
var (
|
||||||
|
decimalByteMap = map[string]uint64{
|
||||||
|
"b": UnitB,
|
||||||
|
"kb": UnitKB,
|
||||||
|
"mb": UnitMB,
|
||||||
|
"gb": UnitGB,
|
||||||
|
"tb": UnitTB,
|
||||||
|
"pb": UnitPB,
|
||||||
|
"eb": UnitEB,
|
||||||
|
|
||||||
|
// Without suffix
|
||||||
|
"": UnitB,
|
||||||
|
"k": UnitKB,
|
||||||
|
"m": UnitMB,
|
||||||
|
"g": UnitGB,
|
||||||
|
"t": UnitTB,
|
||||||
|
"p": UnitPB,
|
||||||
|
"e": UnitEB,
|
||||||
|
}
|
||||||
|
|
||||||
|
binaryByteMap = map[string]uint64{
|
||||||
|
"bi": UnitBiB,
|
||||||
|
"kib": UnitKiB,
|
||||||
|
"mib": UnitMiB,
|
||||||
|
"gib": UnitGiB,
|
||||||
|
"tib": UnitTiB,
|
||||||
|
"pib": UnitPiB,
|
||||||
|
"eib": UnitEiB,
|
||||||
|
|
||||||
|
// Without suffix
|
||||||
|
"": UnitBiB,
|
||||||
|
"ki": UnitKiB,
|
||||||
|
"mi": UnitMiB,
|
||||||
|
"gi": UnitGiB,
|
||||||
|
"ti": UnitTiB,
|
||||||
|
"pi": UnitPiB,
|
||||||
|
"ei": UnitEiB,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
decimalByteUnits = []string{"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}
|
||||||
|
binaryByteUnits = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"}
|
||||||
|
)
|
||||||
|
|
||||||
|
// DecimalBytes returns a human readable byte size under decimal standard (base 1000)
|
||||||
|
// The precision parameter specifies the number of digits after the decimal point, which defaults to 4.
|
||||||
|
// Play: https://go.dev/play/p/FPXs1suwRcs
|
||||||
|
func DecimalBytes(size float64, precision ...int) string {
|
||||||
|
p := 5
|
||||||
|
if len(precision) > 0 {
|
||||||
|
p = precision[0] + 1
|
||||||
|
}
|
||||||
|
size, unit := calculateByteSize(size, 1000.0, decimalByteUnits)
|
||||||
|
|
||||||
|
return fmt.Sprintf("%.*g%s", p, size, unit)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BinaryBytes returns a human-readable byte size under binary standard (base 1024)
|
||||||
|
// The precision parameter specifies the number of digits after the decimal point, which defaults to 4.
|
||||||
|
func BinaryBytes(size float64, precision ...int) string {
|
||||||
|
p := 5
|
||||||
|
if len(precision) > 0 {
|
||||||
|
p = precision[0] + 1
|
||||||
|
}
|
||||||
|
size, unit := calculateByteSize(size, 1024.0, binaryByteUnits)
|
||||||
|
|
||||||
|
return fmt.Sprintf("%.*g%s", p, size, unit)
|
||||||
|
}
|
||||||
|
|
||||||
|
func calculateByteSize(size float64, base float64, byteUnits []string) (float64, string) {
|
||||||
|
i := 0
|
||||||
|
unitsLimit := len(byteUnits) - 1
|
||||||
|
for size >= base && i < unitsLimit {
|
||||||
|
size = size / base
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return size, byteUnits[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseDecimalBytes return the human readable bytes size string into the amount it represents(base 1000).
|
||||||
|
// ParseDecimalBytes("42 MB") -> 42000000, nil
|
||||||
|
func ParseDecimalBytes(size string) (uint64, error) {
|
||||||
|
return parseBytes(size, "decimal")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseBinaryBytes return the human readable bytes size string into the amount it represents(base 1024).
|
||||||
|
// ParseBinaryBytes("42 mib") -> 44040192, nil
|
||||||
|
func ParseBinaryBytes(size string) (uint64, error) {
|
||||||
|
return parseBytes(size, "binary")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +1,134 @@
|
|||||||
package formatter
|
package formatter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"unicode"
|
||||||
)
|
)
|
||||||
|
|
||||||
func commaString(s string) string {
|
// see https://github.com/dustin/go-humanize/blob/master/comma.go
|
||||||
|
func commaInt(v int64) string {
|
||||||
|
sign := ""
|
||||||
|
|
||||||
|
// Min int64 can't be negated to a usable value, so it has to be special cased.
|
||||||
|
if v == math.MinInt64 {
|
||||||
|
return "-9,223,372,036,854,775,808"
|
||||||
|
}
|
||||||
|
|
||||||
|
if v < 0 {
|
||||||
|
sign = "-"
|
||||||
|
v = 0 - v
|
||||||
|
}
|
||||||
|
|
||||||
|
parts := []string{"", "", "", "", "", "", ""}
|
||||||
|
j := len(parts) - 1
|
||||||
|
|
||||||
|
for v > 999 {
|
||||||
|
parts[j] = strconv.FormatInt(v%1000, 10)
|
||||||
|
switch len(parts[j]) {
|
||||||
|
case 2:
|
||||||
|
parts[j] = "0" + parts[j]
|
||||||
|
case 1:
|
||||||
|
parts[j] = "00" + parts[j]
|
||||||
|
}
|
||||||
|
v = v / 1000
|
||||||
|
j--
|
||||||
|
}
|
||||||
|
parts[j] = strconv.Itoa(int(v))
|
||||||
|
return sign + strings.Join(parts[j:], ",")
|
||||||
|
}
|
||||||
|
|
||||||
|
func commaFloat(v float64) string {
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
if v < 0 {
|
||||||
|
buf.Write([]byte{'-'})
|
||||||
|
v = 0 - v
|
||||||
|
}
|
||||||
|
|
||||||
|
comma := []byte{','}
|
||||||
|
|
||||||
|
parts := strings.Split(strconv.FormatFloat(v, 'f', -1, 64), ".")
|
||||||
|
pos := 0
|
||||||
|
if len(parts[0])%3 != 0 {
|
||||||
|
pos += len(parts[0]) % 3
|
||||||
|
buf.WriteString(parts[0][:pos])
|
||||||
|
buf.Write(comma)
|
||||||
|
}
|
||||||
|
for ; pos < len(parts[0]); pos += 3 {
|
||||||
|
buf.WriteString(parts[0][pos : pos+3])
|
||||||
|
buf.Write(comma)
|
||||||
|
}
|
||||||
|
buf.Truncate(buf.Len() - 1)
|
||||||
|
|
||||||
|
if len(parts) > 1 {
|
||||||
|
buf.Write([]byte{'.'})
|
||||||
|
buf.WriteString(parts[1])
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func commaStr(s string) string {
|
||||||
|
dotIndex := strings.Index(s, ".")
|
||||||
|
if dotIndex != -1 {
|
||||||
|
return commaStrRecursive(s[:dotIndex]) + s[dotIndex:]
|
||||||
|
}
|
||||||
|
|
||||||
|
return commaStrRecursive(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func commaStrRecursive(s string) string {
|
||||||
if len(s) <= 3 {
|
if len(s) <= 3 {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
return commaString(s[:len(s)-3]) + "," + commaString(s[len(s)-3:])
|
return commaStrRecursive(s[:len(s)-3]) + "," + commaStrRecursive(s[len(s)-3:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func numString(value any) string {
|
// see https://github.com/dustin/go-humanize/blob/master/bytes.go
|
||||||
switch reflect.TypeOf(value).Kind() {
|
func parseBytes(s string, kind string) (uint64, error) {
|
||||||
case reflect.Int, reflect.Int64, reflect.Float32, reflect.Float64:
|
lastDigit := 0
|
||||||
return fmt.Sprintf("%v", value)
|
hasComma := false
|
||||||
case reflect.String:
|
for _, r := range s {
|
||||||
{
|
if !(unicode.IsDigit(r) || r == '.' || r == ',') {
|
||||||
sv := fmt.Sprintf("%v", value)
|
break
|
||||||
if strings.Contains(sv, ".") {
|
|
||||||
_, err := strconv.ParseFloat(sv, 64)
|
|
||||||
if err == nil {
|
|
||||||
return sv
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_, err := strconv.ParseInt(sv, 10, 64)
|
|
||||||
if err == nil {
|
|
||||||
return sv
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
default:
|
if r == ',' {
|
||||||
return ""
|
hasComma = true
|
||||||
|
}
|
||||||
|
lastDigit++
|
||||||
}
|
}
|
||||||
return ""
|
|
||||||
|
num := s[:lastDigit]
|
||||||
|
if hasComma {
|
||||||
|
num = strings.Replace(num, ",", "", -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := strconv.ParseFloat(num, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
extra := strings.ToLower(strings.TrimSpace(s[lastDigit:]))
|
||||||
|
|
||||||
|
if kind == "decimal" {
|
||||||
|
if m, ok := decimalByteMap[extra]; ok {
|
||||||
|
f *= float64(m)
|
||||||
|
if f >= math.MaxUint64 {
|
||||||
|
return 0, fmt.Errorf("too large: %v", s)
|
||||||
|
}
|
||||||
|
return uint64(f), nil
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if m, ok := binaryByteMap[extra]; ok {
|
||||||
|
f *= float64(m)
|
||||||
|
if f >= math.MaxUint64 {
|
||||||
|
return 0, fmt.Errorf("too large: %v", s)
|
||||||
|
}
|
||||||
|
return uint64(f), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, fmt.Errorf("unhandled size name: %v", extra)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
package formatter
|
package formatter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/duke-git/lancet/v2/internal"
|
"github.com/duke-git/lancet/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestComma(t *testing.T) {
|
func TestComma(t *testing.T) {
|
||||||
@@ -12,12 +13,148 @@ func TestComma(t *testing.T) {
|
|||||||
assert.Equal("", Comma("", ""))
|
assert.Equal("", Comma("", ""))
|
||||||
assert.Equal("", Comma("aa", ""))
|
assert.Equal("", Comma("aa", ""))
|
||||||
assert.Equal("", Comma("aa.a", ""))
|
assert.Equal("", Comma("aa.a", ""))
|
||||||
assert.Equal("", Comma([]int{1}, ""))
|
|
||||||
assert.Equal("123", Comma("123", ""))
|
assert.Equal("123", Comma("123", ""))
|
||||||
assert.Equal("12,345", Comma("12345", ""))
|
assert.Equal("12,345", Comma("12345", ""))
|
||||||
|
assert.Equal("12,345.6789", Comma("12345.6789", ""))
|
||||||
|
assert.Equal("123,456,789,000", Comma("123456789000", ""))
|
||||||
|
assert.Equal("12,345,678.9", Comma("12345678.9", ""))
|
||||||
|
|
||||||
assert.Equal("12,345", Comma(12345, ""))
|
assert.Equal("12,345", Comma(12345, ""))
|
||||||
assert.Equal("$12,345", Comma(12345, "$"))
|
assert.Equal("$12,345", Comma(12345, "$"))
|
||||||
assert.Equal("¥12,345", Comma(12345, "¥"))
|
assert.Equal("¥12,345", Comma(12345, "¥"))
|
||||||
assert.Equal("12,345.6789", Comma(12345.6789, ""))
|
assert.Equal("12,345.6789", Comma(12345.6789, ""))
|
||||||
|
assert.Equal("12,345.6789", Comma(+12345.6789, ""))
|
||||||
|
assert.Equal("12,345,678.9", Comma(12345678.9, ""))
|
||||||
|
assert.Equal("123,456,789,000", Comma(123456789000, ""))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPretty(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestPretty")
|
||||||
|
|
||||||
|
cases := []interface{}{
|
||||||
|
"",
|
||||||
|
"abc",
|
||||||
|
123,
|
||||||
|
[]string{"a", "b", "c"},
|
||||||
|
map[string]int{"a": 1},
|
||||||
|
struct {
|
||||||
|
Abc int `json:"abc"`
|
||||||
|
}{Abc: 123},
|
||||||
|
}
|
||||||
|
|
||||||
|
expects := []string{
|
||||||
|
"\"\"",
|
||||||
|
`"abc"`,
|
||||||
|
"123",
|
||||||
|
"[\n \"a\",\n \"b\",\n \"c\"\n]",
|
||||||
|
"{\n \"a\": 1\n}",
|
||||||
|
"{\n \"abc\": 123\n}",
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, v := range cases {
|
||||||
|
result, err := Pretty(v)
|
||||||
|
|
||||||
|
assert.IsNil(err)
|
||||||
|
|
||||||
|
t.Log("result -> ", result)
|
||||||
|
assert.Equal(expects[i], result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrettyToWriter(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestPrettyToWriter")
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Aage uint `json:"age"`
|
||||||
|
}
|
||||||
|
user := User{Name: "King", Aage: 10000}
|
||||||
|
|
||||||
|
expects := "{\n \"name\": \"King\",\n \"age\": 10000\n}\n"
|
||||||
|
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
err := PrettyToWriter(user, buf)
|
||||||
|
|
||||||
|
assert.IsNil(err)
|
||||||
|
assert.Equal(expects, buf.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDecimalBytes(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestDecimalBytes")
|
||||||
|
|
||||||
|
assert.Equal("1KB", DecimalBytes(1000))
|
||||||
|
assert.Equal("1.024KB", DecimalBytes(1024))
|
||||||
|
assert.Equal("1.2346MB", DecimalBytes(1234567))
|
||||||
|
assert.Equal("1.235MB", DecimalBytes(1234567, 3))
|
||||||
|
assert.Equal("1.123GB", DecimalBytes(float64(1.123*UnitGB)))
|
||||||
|
assert.Equal("2.123TB", DecimalBytes(float64(2.123*UnitTB)))
|
||||||
|
assert.Equal("3.123PB", DecimalBytes(float64(3.123*UnitPB)))
|
||||||
|
assert.Equal("4.123EB", DecimalBytes(float64(4.123*UnitEB)))
|
||||||
|
assert.Equal("1EB", DecimalBytes(float64(1000*UnitPB)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBinaryBytes(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestBinaryBytes")
|
||||||
|
|
||||||
|
assert.Equal("1KiB", BinaryBytes(1024))
|
||||||
|
assert.Equal("1MiB", BinaryBytes(1024*1024))
|
||||||
|
assert.Equal("1.1774MiB", BinaryBytes(1234567))
|
||||||
|
assert.Equal("1.18MiB", BinaryBytes(1234567, 2))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseDecimalBytes(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestParseDecimalBytes")
|
||||||
|
|
||||||
|
cases := map[string]uint64{
|
||||||
|
"12": uint64(12),
|
||||||
|
"12 k": uint64(12000),
|
||||||
|
"12 kb": uint64(12000),
|
||||||
|
"12kb": uint64(12000),
|
||||||
|
"12k": uint64(12000),
|
||||||
|
"12K": uint64(12000),
|
||||||
|
"12KB": uint64(12000),
|
||||||
|
"12 K": uint64(12000),
|
||||||
|
"12 KB": uint64(12000),
|
||||||
|
"12 Kb": uint64(12000),
|
||||||
|
"12 kB": uint64(12000),
|
||||||
|
"12.2 KB": uint64(12200),
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range cases {
|
||||||
|
result, err := ParseDecimalBytes(k)
|
||||||
|
assert.Equal(v, result)
|
||||||
|
assert.IsNil(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := ParseDecimalBytes("12 AB")
|
||||||
|
assert.IsNotNil(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseBinaryBytes(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestParseBinaryBytes")
|
||||||
|
|
||||||
|
cases := map[string]uint64{
|
||||||
|
"12": uint64(12),
|
||||||
|
"12 ki": uint64(12288),
|
||||||
|
"12 kib": uint64(12288),
|
||||||
|
"12kib": uint64(12288),
|
||||||
|
"12ki": uint64(12288),
|
||||||
|
"12KI": uint64(12288),
|
||||||
|
"12KIB": uint64(12288),
|
||||||
|
"12KiB": uint64(12288),
|
||||||
|
"12 Ki": uint64(12288),
|
||||||
|
"12 KiB": uint64(12288),
|
||||||
|
"12 Kib": uint64(12288),
|
||||||
|
"12 kiB": uint64(12288),
|
||||||
|
"12.2 KiB": uint64(12492),
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range cases {
|
||||||
|
result, err := ParseBinaryBytes(k)
|
||||||
|
assert.Equal(v, result)
|
||||||
|
assert.IsNil(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := ParseDecimalBytes("12 AB")
|
||||||
|
assert.IsNotNil(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// After creates a function that invokes func once it's called n or more times
|
// After creates a function that invokes func once it's called n or more times
|
||||||
func After(n int, fn any) func(args ...any) []reflect.Value {
|
func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value {
|
||||||
// Catch programming error while constructing the closure
|
// Catch programming error while constructing the closure
|
||||||
mustBeFunction(fn)
|
mustBeFunction(fn)
|
||||||
|
|
||||||
return func(args ...any) []reflect.Value {
|
return func(args ...interface{}) []reflect.Value {
|
||||||
n--
|
n--
|
||||||
if n < 1 {
|
if n < 1 {
|
||||||
return unsafeInvokeFunc(fn, args...)
|
return unsafeInvokeFunc(fn, args...)
|
||||||
@@ -24,11 +24,11 @@ func After(n int, fn any) func(args ...any) []reflect.Value {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Before creates a function that invokes func once it's called less than n times
|
// Before creates a function that invokes func once it's called less than n times
|
||||||
func Before(n int, fn any) func(args ...any) []reflect.Value {
|
func Before(n int, fn interface{}) func(args ...interface{}) []reflect.Value {
|
||||||
// Catch programming error while constructing the closure
|
// Catch programming error while constructing the closure
|
||||||
mustBeFunction(fn)
|
mustBeFunction(fn)
|
||||||
var res []reflect.Value
|
var res []reflect.Value
|
||||||
return func(args ...any) []reflect.Value {
|
return func(args ...interface{}) []reflect.Value {
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
res = unsafeInvokeFunc(fn, args...)
|
res = unsafeInvokeFunc(fn, args...)
|
||||||
}
|
}
|
||||||
@@ -40,20 +40,20 @@ func Before(n int, fn any) func(args ...any) []reflect.Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fn is for curry function which is func(...any) any
|
// Fn is for curry function which is func(...interface{}) interface{}
|
||||||
type Fn func(...any) any
|
type Fn func(...interface{}) interface{}
|
||||||
|
|
||||||
// Curry make a curry function
|
// Curry make a curry function
|
||||||
func (f Fn) Curry(i any) func(...any) any {
|
func (f Fn) Curry(i interface{}) func(...interface{}) interface{} {
|
||||||
return func(values ...any) any {
|
return func(values ...interface{}) interface{} {
|
||||||
v := append([]any{i}, values...)
|
v := append([]interface{}{i}, values...)
|
||||||
return f(v...)
|
return f(v...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compose compose the functions from right to left
|
// Compose compose the functions from right to left
|
||||||
func Compose(fnList ...func(...any) any) func(...any) any {
|
func Compose(fnList ...func(...interface{}) interface{}) func(...interface{}) interface{} {
|
||||||
return func(s ...any) any {
|
return func(s ...interface{}) interface{} {
|
||||||
f := fnList[0]
|
f := fnList[0]
|
||||||
restFn := fnList[1:]
|
restFn := fnList[1:]
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ func Compose(fnList ...func(...any) any) func(...any) any {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delay make the function execution after delayed time
|
// Delay make the function execution after delayed time
|
||||||
func Delay(delay time.Duration, fn any, args ...any) {
|
func Delay(delay time.Duration, fn interface{}, args ...interface{}) {
|
||||||
// Catch programming error while constructing the closure
|
// Catch programming error while constructing the closure
|
||||||
mustBeFunction(fn)
|
mustBeFunction(fn)
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ func Debounced(fn func(), duration time.Duration) func() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Schedule invoke function every duration time, util close the returned bool chan
|
// Schedule invoke function every duration time, util close the returned bool chan
|
||||||
func Schedule(d time.Duration, fn any, args ...any) chan bool {
|
func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool {
|
||||||
// Catch programming error while constructing the closure
|
// Catch programming error while constructing the closure
|
||||||
mustBeFunction(fn)
|
mustBeFunction(fn)
|
||||||
|
|
||||||
@@ -113,3 +113,15 @@ func Schedule(d time.Duration, fn any, args ...any) chan bool {
|
|||||||
|
|
||||||
return quit
|
return quit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pipeline takes a list of functions and returns a function whose param will be passed into
|
||||||
|
// the functions one by one.
|
||||||
|
func Pipeline(funcs ...func(interface{}) interface{}) func(interface{}) interface{} {
|
||||||
|
return func(arg interface{}) (result interface{}) {
|
||||||
|
result = arg
|
||||||
|
for _, fn := range funcs {
|
||||||
|
result = fn(result)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
func invokeFunc(fn any, args ...any) []reflect.Value {
|
func invokeFunc(fn interface{}, args ...interface{}) []reflect.Value {
|
||||||
fv := functionValue(fn)
|
fv := functionValue(fn)
|
||||||
params := make([]reflect.Value, len(args))
|
params := make([]reflect.Value, len(args))
|
||||||
for i, item := range args {
|
for i, item := range args {
|
||||||
@@ -14,7 +14,7 @@ func invokeFunc(fn any, args ...any) []reflect.Value {
|
|||||||
return fv.Call(params)
|
return fv.Call(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
func unsafeInvokeFunc(fn any, args ...any) []reflect.Value {
|
func unsafeInvokeFunc(fn interface{}, args ...interface{}) []reflect.Value {
|
||||||
fv := reflect.ValueOf(fn)
|
fv := reflect.ValueOf(fn)
|
||||||
params := make([]reflect.Value, len(args))
|
params := make([]reflect.Value, len(args))
|
||||||
for i, item := range args {
|
for i, item := range args {
|
||||||
@@ -23,7 +23,7 @@ func unsafeInvokeFunc(fn any, args ...any) []reflect.Value {
|
|||||||
return fv.Call(params)
|
return fv.Call(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
func functionValue(function any) reflect.Value {
|
func functionValue(function interface{}) reflect.Value {
|
||||||
v := reflect.ValueOf(function)
|
v := reflect.ValueOf(function)
|
||||||
if v.Kind() != reflect.Func {
|
if v.Kind() != reflect.Func {
|
||||||
panic(fmt.Sprintf("Invalid function type, value of type %T", function))
|
panic(fmt.Sprintf("Invalid function type, value of type %T", function))
|
||||||
@@ -31,7 +31,7 @@ func functionValue(function any) reflect.Value {
|
|||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustBeFunction(function any) {
|
func mustBeFunction(function interface{}) {
|
||||||
v := reflect.ValueOf(function)
|
v := reflect.ValueOf(function)
|
||||||
if v.Kind() != reflect.Func {
|
if v.Kind() != reflect.Func {
|
||||||
panic(fmt.Sprintf("Invalid function type, value of type %T", function))
|
panic(fmt.Sprintf("Invalid function type, value of type %T", function))
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/duke-git/lancet/v2/internal"
|
"github.com/duke-git/lancet/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAfter(t *testing.T) {
|
func TestAfter(t *testing.T) {
|
||||||
@@ -16,7 +16,7 @@ func TestAfter(t *testing.T) {
|
|||||||
fmt.Println("print done")
|
fmt.Println("print done")
|
||||||
return i
|
return i
|
||||||
})
|
})
|
||||||
type cb func(args ...any) []reflect.Value
|
type cb func(args ...interface{}) []reflect.Value
|
||||||
print := func(i int, s string, fn cb) {
|
print := func(i int, s string, fn cb) {
|
||||||
fmt.Printf("print: arr[%d] is %s \n", i, s)
|
fmt.Printf("print: arr[%d] is %s \n", i, s)
|
||||||
v := fn(i)
|
v := fn(i)
|
||||||
@@ -42,7 +42,7 @@ func TestBefore(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
var res []int64
|
var res []int64
|
||||||
type cb func(args ...any) []reflect.Value
|
type cb func(args ...interface{}) []reflect.Value
|
||||||
appendStr := func(i int, s string, fn cb) {
|
appendStr := func(i int, s string, fn cb) {
|
||||||
v := fn(i)
|
v := fn(i)
|
||||||
res = append(res, v[0].Int())
|
res = append(res, v[0].Int())
|
||||||
@@ -62,7 +62,7 @@ func TestCurry(t *testing.T) {
|
|||||||
add := func(a, b int) int {
|
add := func(a, b int) int {
|
||||||
return a + b
|
return a + b
|
||||||
}
|
}
|
||||||
var addCurry Fn = func(values ...any) any {
|
var addCurry Fn = func(values ...interface{}) interface{} {
|
||||||
return add(values[0].(int), values[1].(int))
|
return add(values[0].(int), values[1].(int))
|
||||||
}
|
}
|
||||||
add1 := addCurry.Curry(1)
|
add1 := addCurry.Curry(1)
|
||||||
@@ -72,10 +72,10 @@ func TestCurry(t *testing.T) {
|
|||||||
func TestCompose(t *testing.T) {
|
func TestCompose(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestCompose")
|
assert := internal.NewAssert(t, "TestCompose")
|
||||||
|
|
||||||
toUpper := func(a ...any) any {
|
toUpper := func(a ...interface{}) interface{} {
|
||||||
return strings.ToUpper(a[0].(string))
|
return strings.ToUpper(a[0].(string))
|
||||||
}
|
}
|
||||||
toLower := func(a ...any) any {
|
toLower := func(a ...interface{}) interface{} {
|
||||||
return strings.ToLower(a[0].(string))
|
return strings.ToLower(a[0].(string))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,3 +130,21 @@ func TestSchedule(t *testing.T) {
|
|||||||
expected := []string{"*", "*", "*", "*", "*"}
|
expected := []string{"*", "*", "*", "*", "*"}
|
||||||
assert.Equal(expected, res)
|
assert.Equal(expected, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPipeline(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestPipeline")
|
||||||
|
|
||||||
|
addOne := func(x interface{}) interface{} {
|
||||||
|
return x.(int) + 1
|
||||||
|
}
|
||||||
|
double := func(x interface{}) interface{} {
|
||||||
|
return 2 * x.(int)
|
||||||
|
}
|
||||||
|
square := func(x interface{}) interface{} {
|
||||||
|
return x.(int) * x.(int)
|
||||||
|
}
|
||||||
|
|
||||||
|
f := Pipeline(addOne, double, square)
|
||||||
|
|
||||||
|
assert.Equal(36, f(2))
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package function
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/duke-git/lancet/v2/internal"
|
"github.com/duke-git/lancet/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestWatcher(t *testing.T) {
|
func TestWatcher(t *testing.T) {
|
||||||
|
|||||||
6
go.mod
6
go.mod
@@ -1,3 +1,5 @@
|
|||||||
module github.com/duke-git/lancet/v2
|
module github.com/duke-git/lancet
|
||||||
|
|
||||||
go 1.18
|
go 1.16
|
||||||
|
|
||||||
|
require golang.org/x/text v0.5.0
|
||||||
|
|||||||
25
go.sum
Normal file
25
go.sum
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
|
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
|
||||||
|
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user