mirror of
https://github.com/duke-git/lancet.git
synced 2026-03-01 00:35:28 +08:00
Compare commits
16 Commits
v2.1.5
...
ef28b52963
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef28b52963 | ||
|
|
18b2b6ff7c | ||
|
|
6a05a123f4 | ||
|
|
f7c33f258d | ||
|
|
04058dd7da | ||
|
|
72e1d92fa1 | ||
|
|
063df0f0d1 | ||
|
|
fc10689b25 | ||
|
|
9239bcfdc3 | ||
|
|
c984815dea | ||
|
|
301cb5db87 | ||
|
|
cc1bacff74 | ||
|
|
f49f75b371 | ||
|
|
b30f4a7bab | ||
|
|
982cb8932b | ||
|
|
9107eb4b32 |
@@ -219,6 +219,7 @@ import queue "github.com/duke-git/lancet/v2/datastructure/queue"
|
|||||||
import set "github.com/duke-git/lancet/v2/datastructure/set"
|
import set "github.com/duke-git/lancet/v2/datastructure/set"
|
||||||
import tree "github.com/duke-git/lancet/v2/datastructure/tree"
|
import tree "github.com/duke-git/lancet/v2/datastructure/tree"
|
||||||
import heap "github.com/duke-git/lancet/v2/datastructure/heap"
|
import heap "github.com/duke-git/lancet/v2/datastructure/heap"
|
||||||
|
import hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
```
|
```
|
||||||
#### Function list:
|
#### Function list:
|
||||||
- [List](https://github.com/duke-git/lancet/blob/main/docs/datastructure/list.md)
|
- [List](https://github.com/duke-git/lancet/blob/main/docs/datastructure/list.md)
|
||||||
@@ -228,6 +229,7 @@ import heap "github.com/duke-git/lancet/v2/datastructure/heap"
|
|||||||
- [Set](https://github.com/duke-git/lancet/blob/main/docs/datastructure/set.md)
|
- [Set](https://github.com/duke-git/lancet/blob/main/docs/datastructure/set.md)
|
||||||
- [Tree](https://github.com/duke-git/lancet/blob/main/docs/datastructure/tree.md)
|
- [Tree](https://github.com/duke-git/lancet/blob/main/docs/datastructure/tree.md)
|
||||||
- [Heap](https://github.com/duke-git/lancet/blob/main/docs/datastructure/heap.md)
|
- [Heap](https://github.com/duke-git/lancet/blob/main/docs/datastructure/heap.md)
|
||||||
|
- [HashMap](https://github.com/duke-git/lancet/blob/main/docs/datastructure/hashmap.md)
|
||||||
|
|
||||||
|
|
||||||
### 7. Fileutil package implements some basic functions for file operations.
|
### 7. Fileutil package implements some basic functions for file operations.
|
||||||
@@ -491,6 +493,7 @@ import "github.com/duke-git/lancet/v2/validator"
|
|||||||
- [IsStrongPassword](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsStrongPassword)
|
- [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)
|
- [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)
|
- [IsWeakPassword](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsWeakPassword)
|
||||||
|
- [IsZeroValue](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsZeroValue)
|
||||||
### 19. xerror package implements helpers for errors.
|
### 19. xerror package implements helpers for errors.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
|||||||
@@ -216,6 +216,7 @@ import queue "github.com/duke-git/lancet/v2/datastructure/queue"
|
|||||||
import set "github.com/duke-git/lancet/v2/datastructure/set"
|
import set "github.com/duke-git/lancet/v2/datastructure/set"
|
||||||
import tree "github.com/duke-git/lancet/v2/datastructure/tree"
|
import tree "github.com/duke-git/lancet/v2/datastructure/tree"
|
||||||
import heap "github.com/duke-git/lancet/v2/datastructure/heap"
|
import heap "github.com/duke-git/lancet/v2/datastructure/heap"
|
||||||
|
import hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||||
```
|
```
|
||||||
#### Function list:
|
#### Function list:
|
||||||
- [List](https://github.com/duke-git/lancet/blob/main/docs/datastructure/list_zh-CN.md)
|
- [List](https://github.com/duke-git/lancet/blob/main/docs/datastructure/list_zh-CN.md)
|
||||||
@@ -225,6 +226,7 @@ import heap "github.com/duke-git/lancet/v2/datastructure/heap"
|
|||||||
- [Set](https://github.com/duke-git/lancet/blob/main/docs/datastructure/set_zh-CN.md)
|
- [Set](https://github.com/duke-git/lancet/blob/main/docs/datastructure/set_zh-CN.md)
|
||||||
- [Tree](https://github.com/duke-git/lancet/blob/main/docs/datastructure/tree_zh-CN.md)
|
- [Tree](https://github.com/duke-git/lancet/blob/main/docs/datastructure/tree_zh-CN.md)
|
||||||
- [Heap](https://github.com/duke-git/lancet/blob/main/docs/datastructure/heap.md)
|
- [Heap](https://github.com/duke-git/lancet/blob/main/docs/datastructure/heap.md)
|
||||||
|
- [HashMap](https://github.com/duke-git/lancet/blob/main/docs/datastructure/hashmap.md)
|
||||||
|
|
||||||
|
|
||||||
### 7. fileutil包支持文件基本操作。
|
### 7. fileutil包支持文件基本操作。
|
||||||
@@ -488,6 +490,7 @@ import "github.com/duke-git/lancet/v2/validator"
|
|||||||
- [IsStrongPassword](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsStrongPassword)
|
- [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)
|
- [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)
|
- [IsWeakPassword](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsWeakPassword)
|
||||||
|
- [IsZeroValue](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsZeroValue)
|
||||||
|
|
||||||
### 19. xerror包实现一些错误处理函数
|
### 19. xerror包实现一些错误处理函数
|
||||||
|
|
||||||
|
|||||||
77
condition/condition.go
Normal file
77
condition/condition.go
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
|
||||||
|
// Use of this source code is governed by MIT license
|
||||||
|
|
||||||
|
// Package condition contains some functions for conditional judgment. eg. And, Or, TernaryOperator ...
|
||||||
|
// The implementation of this package refers to the implementation of carlmjohnson's truthy package, you may find more
|
||||||
|
// useful information in truthy(https://github.com/carlmjohnson/truthy), thanks carlmjohnson.
|
||||||
|
package condition
|
||||||
|
|
||||||
|
import "reflect"
|
||||||
|
|
||||||
|
// Bool returns the truthy value of anything.
|
||||||
|
// If the value's type has a Bool() bool method, the method is called and returned.
|
||||||
|
// If the type has an IsZero() bool method, the opposite value is returned.
|
||||||
|
// Slices and maps are truthy if they have a length greater than zero.
|
||||||
|
// All other types are truthy if they are not their zero value.
|
||||||
|
func Bool[T any](value T) bool {
|
||||||
|
switch m := any(value).(type) {
|
||||||
|
case interface{ Bool() bool }:
|
||||||
|
return m.Bool()
|
||||||
|
case interface{ IsZero() bool }:
|
||||||
|
return !m.IsZero()
|
||||||
|
}
|
||||||
|
return reflectValue(&value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func reflectValue(vp any) bool {
|
||||||
|
switch rv := reflect.ValueOf(vp).Elem(); rv.Kind() {
|
||||||
|
case reflect.Map, reflect.Slice:
|
||||||
|
return rv.Len() != 0
|
||||||
|
default:
|
||||||
|
is := rv.IsZero()
|
||||||
|
return !is
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// And returns true if both a and b are truthy.
|
||||||
|
func And[T, U any](a T, b U) bool {
|
||||||
|
return Bool(a) && Bool(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Or returns false iff neither a nor b is truthy.
|
||||||
|
func Or[T, U any](a T, b U) bool {
|
||||||
|
return Bool(a) || Bool(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Xor returns true iff a or b but not both is truthy.
|
||||||
|
func Xor[T, U any](a T, b U) bool {
|
||||||
|
valA := Bool(a)
|
||||||
|
valB := Bool(b)
|
||||||
|
return (valA || valB) && valA != valB
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nor returns true iff neither a nor b is truthy.
|
||||||
|
func Nor[T, U any](a T, b U) bool {
|
||||||
|
return !(Bool(a) || Bool(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Xnor returns true iff both a and b or neither a nor b are truthy.
|
||||||
|
func Xnor[T, U any](a T, b U) bool {
|
||||||
|
valA := Bool(a)
|
||||||
|
valB := Bool(b)
|
||||||
|
return (valA && valB) || (!valA && !valB)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nand returns false iff both a and b are truthy.
|
||||||
|
func Nand[T, U any](a T, b U) bool {
|
||||||
|
return !Bool(a) || !Bool(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TernaryOperator if true return trueValue else return falseValue
|
||||||
|
func TernaryOperator[T any](isTrue bool, trueValue T, falseValue T) T {
|
||||||
|
if isTrue {
|
||||||
|
return trueValue
|
||||||
|
} else {
|
||||||
|
return falseValue
|
||||||
|
}
|
||||||
|
}
|
||||||
119
condition/condition_test.go
Normal file
119
condition/condition_test.go
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
package condition
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/v2/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TestStruct struct{}
|
||||||
|
|
||||||
|
func TestBool(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestBool")
|
||||||
|
|
||||||
|
// bool
|
||||||
|
assert.Equal(false, Bool(false))
|
||||||
|
assert.Equal(true, Bool(true))
|
||||||
|
|
||||||
|
// integer
|
||||||
|
assert.Equal(false, Bool(0))
|
||||||
|
assert.Equal(true, Bool(1))
|
||||||
|
|
||||||
|
// float
|
||||||
|
assert.Equal(false, Bool(0.0))
|
||||||
|
assert.Equal(true, Bool(0.1))
|
||||||
|
|
||||||
|
// string
|
||||||
|
assert.Equal(false, Bool(""))
|
||||||
|
assert.Equal(true, Bool(" "))
|
||||||
|
assert.Equal(true, Bool("0"))
|
||||||
|
|
||||||
|
// slice
|
||||||
|
var nums [2]int
|
||||||
|
assert.Equal(false, Bool(nums))
|
||||||
|
nums = [2]int{0, 1}
|
||||||
|
assert.Equal(true, Bool(nums))
|
||||||
|
|
||||||
|
// map
|
||||||
|
assert.Equal(false, Bool(map[string]string{}))
|
||||||
|
assert.Equal(true, Bool(map[string]string{"a": "a"}))
|
||||||
|
|
||||||
|
// channel
|
||||||
|
var ch chan int
|
||||||
|
assert.Equal(false, Bool(ch))
|
||||||
|
ch = make(chan int)
|
||||||
|
assert.Equal(true, Bool(ch))
|
||||||
|
|
||||||
|
// interface
|
||||||
|
var err error
|
||||||
|
assert.Equal(false, Bool(err))
|
||||||
|
err = errors.New("error message")
|
||||||
|
assert.Equal(true, Bool(err))
|
||||||
|
|
||||||
|
// struct
|
||||||
|
assert.Equal(false, Bool(struct{}{}))
|
||||||
|
assert.Equal(true, Bool(time.Now()))
|
||||||
|
|
||||||
|
// struct pointer
|
||||||
|
ts := TestStruct{}
|
||||||
|
assert.Equal(false, Bool(ts))
|
||||||
|
assert.Equal(true, Bool(&ts))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAnd(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestAnd")
|
||||||
|
assert.Equal(false, And(0, 1))
|
||||||
|
assert.Equal(false, And(0, ""))
|
||||||
|
assert.Equal(false, And(0, "0"))
|
||||||
|
assert.Equal(true, And(1, "0"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOr(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestOr")
|
||||||
|
assert.Equal(false, Or(0, ""))
|
||||||
|
assert.Equal(true, Or(0, 1))
|
||||||
|
assert.Equal(true, Or(0, "0"))
|
||||||
|
assert.Equal(true, Or(1, "0"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestXor(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestOr")
|
||||||
|
assert.Equal(false, Xor(0, 0))
|
||||||
|
assert.Equal(true, Xor(0, 1))
|
||||||
|
assert.Equal(true, Xor(1, 0))
|
||||||
|
assert.Equal(false, Xor(1, 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNor(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestNor")
|
||||||
|
assert.Equal(true, Nor(0, 0))
|
||||||
|
assert.Equal(false, Nor(0, 1))
|
||||||
|
assert.Equal(false, Nor(1, 0))
|
||||||
|
assert.Equal(false, Nor(1, 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestXnor(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestXnor")
|
||||||
|
assert.Equal(true, Xnor(0, 0))
|
||||||
|
assert.Equal(false, Xnor(0, 1))
|
||||||
|
assert.Equal(false, Xnor(1, 0))
|
||||||
|
assert.Equal(true, Xnor(1, 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNand(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestNand")
|
||||||
|
assert.Equal(true, Nand(0, 0))
|
||||||
|
assert.Equal(true, Nand(0, 1))
|
||||||
|
assert.Equal(true, Nand(1, 0))
|
||||||
|
assert.Equal(false, Nand(1, 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTernaryOperator(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TernaryOperator")
|
||||||
|
trueValue := "1"
|
||||||
|
falseValue := "0"
|
||||||
|
|
||||||
|
assert.Equal(trueValue, TernaryOperator(true, trueValue, falseValue))
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ package convertor
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"encoding/gob"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
@@ -270,3 +271,21 @@ func ColorRGBToHex(red, green, blue int) string {
|
|||||||
|
|
||||||
return "#" + r + g + b
|
return "#" + r + g + b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EncodeByte encode data to byte
|
||||||
|
func EncodeByte(data any) ([]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 any) error {
|
||||||
|
buffer := bytes.NewBuffer(data)
|
||||||
|
decoder := gob.NewDecoder(buffer)
|
||||||
|
return decoder.Decode(target)
|
||||||
|
}
|
||||||
|
|||||||
@@ -238,3 +238,21 @@ func TestToPointer(t *testing.T) {
|
|||||||
|
|
||||||
assert.Equal(*result, 123)
|
assert.Equal(*result, 123)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|||||||
@@ -98,6 +98,8 @@ func (hm *HashMap) resize() {
|
|||||||
|
|
||||||
tempTable := hm.table
|
tempTable := hm.table
|
||||||
|
|
||||||
|
hm.table = make([]*mapNode, hm.capacity)
|
||||||
|
|
||||||
for i := 0; i < len(tempTable); i++ {
|
for i := 0; i < len(tempTable); i++ {
|
||||||
node := tempTable[i]
|
node := tempTable[i]
|
||||||
if node == nil {
|
if node == nil {
|
||||||
|
|||||||
@@ -19,6 +19,18 @@ func TestHashMap_PutAndGet(t *testing.T) {
|
|||||||
assert.Equal(4, hm.Get("abc"))
|
assert.Equal(4, hm.Get("abc"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHashMap_Resize(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestHashMap_Resize")
|
||||||
|
|
||||||
|
hm := NewHashMapWithCapacity(3, 3)
|
||||||
|
|
||||||
|
for i := 0; i < 20; i++ {
|
||||||
|
hm.Put(i, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(10, hm.Get(5))
|
||||||
|
}
|
||||||
|
|
||||||
func TestHashMap_Delete(t *testing.T) {
|
func TestHashMap_Delete(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestHashMap_Delete")
|
assert := internal.NewAssert(t, "TestHashMap_Delete")
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ import (
|
|||||||
- [ToString](#ToString)
|
- [ToString](#ToString)
|
||||||
- [StructToMap](#StructToMap)
|
- [StructToMap](#StructToMap)
|
||||||
- [MapToSlice](#MapToSlice)
|
- [MapToSlice](#MapToSlice)
|
||||||
|
- [EncodeByte](#EncodeByte)
|
||||||
|
- [DecodeByte](#DecodeByte)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
@@ -457,4 +459,59 @@ func main() {
|
|||||||
|
|
||||||
fmt.Println(result) //[]string{"a:1", "b:2", "c:3"}
|
fmt.Println(result) //[]string{"a:1", "b:2", "c:3"}
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <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/v2/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/v2/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var result string
|
||||||
|
byteData := []byte{6, 12, 0, 3, 97, 98, 99}
|
||||||
|
convertor.DecodeByte(byteData, &result)
|
||||||
|
fmt.Println(result) //"abc"
|
||||||
|
}
|
||||||
```
|
```
|
||||||
@@ -36,6 +36,8 @@ import (
|
|||||||
- [ToString](#ToString)
|
- [ToString](#ToString)
|
||||||
- [StructToMap](#StructToMap)
|
- [StructToMap](#StructToMap)
|
||||||
- [MapToSlice](#MapToSlice)
|
- [MapToSlice](#MapToSlice)
|
||||||
|
- [EncodeByte](#EncodeByte)
|
||||||
|
- [DecodeByte](#DecodeByte)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
@@ -489,3 +491,59 @@ func main() {
|
|||||||
fmt.Println(result) //[]string{"a:1", "b:2", "c:3"}
|
fmt.Println(result) //[]string{"a:1", "b:2", "c:3"}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <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/v2/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/v2/convertor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var result string
|
||||||
|
byteData := []byte{6, 12, 0, 3, 97, 98, 99}
|
||||||
|
convertor.DecodeByte(byteData, &result)
|
||||||
|
fmt.Println(result) //"abc"
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -20,6 +20,7 @@ import (
|
|||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
|
||||||
## Index
|
## Index
|
||||||
|
|
||||||
- [NewHashMap](#NewHashMap)
|
- [NewHashMap](#NewHashMap)
|
||||||
@@ -106,8 +107,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
hm := heap.NewHashMap()
|
hm := heap.NewHashMap()
|
||||||
val := hm.Get("a")
|
val := hm.Get("a")
|
||||||
|
|
||||||
fmt.Println(val) //nil
|
fmt.Println(val) //nil
|
||||||
}
|
}
|
||||||
@@ -134,10 +135,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
hm := heap.NewHashMap()
|
hm := heap.NewHashMap()
|
||||||
hm.Put("a", 1)
|
hm.Put("a", 1)
|
||||||
|
|
||||||
val := hm.Get("a")
|
val := hm.Get("a")
|
||||||
fmt.Println(val) //1
|
fmt.Println(val) //1
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -165,13 +166,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
hm := heap.NewHashMap()
|
hm := heap.NewHashMap()
|
||||||
hm.Put("a", 1)
|
hm.Put("a", 1)
|
||||||
val := hm.Get("a")
|
val := hm.Get("a")
|
||||||
fmt.Println(val) //1
|
fmt.Println(val) //1
|
||||||
|
|
||||||
hm.Delete("a")
|
hm.Delete("a")
|
||||||
val = hm.Get("a")
|
val = hm.Get("a")
|
||||||
fmt.Println(val) //nil
|
fmt.Println(val) //nil
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -199,8 +200,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
hm := heap.NewHashMap()
|
hm := heap.NewHashMap()
|
||||||
hm.Put("a", 1)
|
hm.Put("a", 1)
|
||||||
|
|
||||||
fmt.Println(hm.Contains("a")) //true
|
fmt.Println(hm.Contains("a")) //true
|
||||||
fmt.Println(hm.Contains("b")) //false
|
fmt.Println(hm.Contains("b")) //false
|
||||||
|
|||||||
@@ -22,17 +22,13 @@ import (
|
|||||||
|
|
||||||
## 目录
|
## 目录
|
||||||
|
|
||||||
- [HashMap](#hashmap)
|
- [NewHashMap](#NewHashMap)
|
||||||
- [源码](#源码)
|
- [NewHashMapWithCapacity](#NewHashMapWithCapacity)
|
||||||
- [用法](#用法)
|
|
||||||
- [目录](#目录)
|
- [Get](#Get)
|
||||||
- [API 文档](#api-文档)
|
- [Put](#Put)
|
||||||
- [<span id="NewHashMap">NewHashMap</span>](#newhashmap)
|
- [Delete](#Delete)
|
||||||
- [<span id="NewHashMapWithCapacity">NewHashMapWithCapacity</span>](#newhashmapwithcapacity)
|
- [Contains](#Contains)
|
||||||
- [<span id="Get">Get</span>](#get)
|
|
||||||
- [<span id="Put">Put</span>](#put)
|
|
||||||
- [<span id="Delete">Delete</span>](#delete)
|
|
||||||
- [<span id="Contains">Contains</span>](#contains)
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
@@ -111,8 +107,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
hm := heap.NewHashMap()
|
hm := heap.NewHashMap()
|
||||||
val := hm.Get("a")
|
val := hm.Get("a")
|
||||||
|
|
||||||
fmt.Println(val) //nil
|
fmt.Println(val) //nil
|
||||||
}
|
}
|
||||||
@@ -139,10 +135,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
hm := heap.NewHashMap()
|
hm := heap.NewHashMap()
|
||||||
hm.Put("a", 1)
|
hm.Put("a", 1)
|
||||||
|
|
||||||
val := hm.Get("a")
|
val := hm.Get("a")
|
||||||
fmt.Println(val) //1
|
fmt.Println(val) //1
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -168,13 +164,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
hm := heap.NewHashMap()
|
hm := heap.NewHashMap()
|
||||||
hm.Put("a", 1)
|
hm.Put("a", 1)
|
||||||
val := hm.Get("a")
|
val := hm.Get("a")
|
||||||
fmt.Println(val) //1
|
fmt.Println(val) //1
|
||||||
|
|
||||||
hm.Delete("a")
|
hm.Delete("a")
|
||||||
val = hm.Get("a")
|
val = hm.Get("a")
|
||||||
fmt.Println(val) //nil
|
fmt.Println(val) //nil
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -200,8 +196,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
hm := heap.NewHashMap()
|
hm := heap.NewHashMap()
|
||||||
hm.Put("a", 1)
|
hm.Put("a", 1)
|
||||||
|
|
||||||
fmt.Println(hm.Contains("a")) //true
|
fmt.Println(hm.Contains("a")) //true
|
||||||
fmt.Println(hm.Contains("b")) //false
|
fmt.Println(hm.Contains("b")) //false
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import (
|
|||||||
- [IsStrongPassword](#IsStrongPassword)
|
- [IsStrongPassword](#IsStrongPassword)
|
||||||
- [IsUrl](#IsUrl)
|
- [IsUrl](#IsUrl)
|
||||||
- [IsWeakPassword](#IsWeakPassword)
|
- [IsWeakPassword](#IsWeakPassword)
|
||||||
|
- [IsZeroValue](#IsZeroValue)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
@@ -765,7 +766,7 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
### <span id="IsWeakPassword">IsWeakPassword</span>
|
### <span id="IsWeakPassword">IsWeakPassword</span>
|
||||||
<p>Check if the string is weak password(only letter or only number or letter + number)
|
<p>Checks if the string is weak password(only letter or only number or letter + number)
|
||||||
.</p>
|
.</p>
|
||||||
|
|
||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
@@ -792,6 +793,36 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="IsZeroValue">IsZeroValue</span>
|
||||||
|
<p>Checks if passed value is a zero value.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func IsZeroValue(value any) bool
|
||||||
|
```
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/validator"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(validator.IsZeroValue(nil)) //true
|
||||||
|
fmt.Println(validator.IsZeroValue(0)) //true
|
||||||
|
fmt.Println(validator.IsZeroValue("")) //true
|
||||||
|
fmt.Println(validator.IsZeroValue([]int)) //true
|
||||||
|
fmt.Println(validator.IsZeroValue(interface{})) //true
|
||||||
|
|
||||||
|
fmt.Println(validator.IsZeroValue("0")) //false
|
||||||
|
fmt.Println(validator.IsZeroValue("nil")) //false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import (
|
|||||||
- [IsStrongPassword](#IsStrongPassword)
|
- [IsStrongPassword](#IsStrongPassword)
|
||||||
- [IsUrl](#IsUrl)
|
- [IsUrl](#IsUrl)
|
||||||
- [IsWeakPassword](#IsWeakPassword)
|
- [IsWeakPassword](#IsWeakPassword)
|
||||||
|
- [IsZeroValue](#IsZeroValue)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
@@ -792,8 +793,31 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="IsZeroValue">IsZeroValue</span>
|
||||||
|
<p>判断传入的参数值是否为零值</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func IsZeroValue(value any) bool
|
||||||
|
```
|
||||||
|
<b>例子:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/validator"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(validator.IsZeroValue(nil)) //true
|
||||||
|
fmt.Println(validator.IsZeroValue(0)) //true
|
||||||
|
fmt.Println(validator.IsZeroValue("")) //true
|
||||||
|
fmt.Println(validator.IsZeroValue([]int)) //true
|
||||||
|
fmt.Println(validator.IsZeroValue(interface{})) //true
|
||||||
|
|
||||||
|
fmt.Println(validator.IsZeroValue("0")) //false
|
||||||
|
fmt.Println(validator.IsZeroValue("nil")) //false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
_, err := strconv.Atoi("4o2")
|
_, err := strconv.Atoi("4o2")
|
||||||
defer func() {
|
defer func() {
|
||||||
v := recover()
|
v := recover()
|
||||||
fmt.Println(err.Error()) // err.Error() == v.(*strconv.NumError).Error()
|
fmt.Println(err.Error()) // err.Error() == v.(*strconv.NumError).Error()
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
_, err := strconv.Atoi("4o2")
|
_, err := strconv.Atoi("4o2")
|
||||||
defer func() {
|
defer func() {
|
||||||
v := recover()
|
v := recover()
|
||||||
fmt.Println(err.Error()) // err.Error() == v.(*strconv.NumError).Error()
|
fmt.Println(err.Error()) // err.Error() == v.(*strconv.NumError).Error()
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -253,3 +254,32 @@ func IsWeakPassword(password string) bool {
|
|||||||
|
|
||||||
return (num || letter) && !special
|
return (num || letter) && !special
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsZeroValue checks if value is a zero value
|
||||||
|
func IsZeroValue(value any) bool {
|
||||||
|
if value == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
rv := reflect.ValueOf(value)
|
||||||
|
if !rv.IsValid() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch rv.Kind() {
|
||||||
|
case reflect.String:
|
||||||
|
return rv.Len() == 0
|
||||||
|
case reflect.Bool:
|
||||||
|
return !rv.Bool()
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return rv.Int() == 0
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
return rv.Uint() == 0
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return rv.Float() == 0
|
||||||
|
case reflect.Ptr, reflect.Chan, reflect.Func, reflect.Interface, reflect.Slice, reflect.Map:
|
||||||
|
return rv.IsNil()
|
||||||
|
}
|
||||||
|
|
||||||
|
return reflect.DeepEqual(rv.Interface(), reflect.Zero(rv.Type()).Interface())
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package validator
|
package validator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/duke-git/lancet/v2/internal"
|
"github.com/duke-git/lancet/v2/internal"
|
||||||
)
|
)
|
||||||
@@ -279,3 +281,110 @@ func TestIsWeakPassword(t *testing.T) {
|
|||||||
assert.Equal(true, IsWeakPassword("abcABC123"))
|
assert.Equal(true, IsWeakPassword("abcABC123"))
|
||||||
assert.Equal(false, IsWeakPassword("abc123@#$"))
|
assert.Equal(false, IsWeakPassword("abc123@#$"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIsZeroValue(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestIsZeroValue")
|
||||||
|
|
||||||
|
var (
|
||||||
|
zeroPtr *string
|
||||||
|
zeroSlice []int
|
||||||
|
zeroFunc func() string
|
||||||
|
zeroMap map[string]string
|
||||||
|
nilIface interface{}
|
||||||
|
zeroIface fmt.Formatter
|
||||||
|
)
|
||||||
|
zeroValues := []interface{}{
|
||||||
|
nil,
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
int8(0),
|
||||||
|
int16(0),
|
||||||
|
int32(0),
|
||||||
|
int64(0),
|
||||||
|
uint(0),
|
||||||
|
uint8(0),
|
||||||
|
uint16(0),
|
||||||
|
uint32(0),
|
||||||
|
uint64(0),
|
||||||
|
|
||||||
|
0.0,
|
||||||
|
float32(0.0),
|
||||||
|
float64(0.0),
|
||||||
|
|
||||||
|
"",
|
||||||
|
|
||||||
|
// func
|
||||||
|
zeroFunc,
|
||||||
|
|
||||||
|
// array / slice
|
||||||
|
[0]int{},
|
||||||
|
zeroSlice,
|
||||||
|
|
||||||
|
// map
|
||||||
|
zeroMap,
|
||||||
|
|
||||||
|
// interface
|
||||||
|
nilIface,
|
||||||
|
zeroIface,
|
||||||
|
|
||||||
|
// pointer
|
||||||
|
zeroPtr,
|
||||||
|
|
||||||
|
// struct
|
||||||
|
time.Time{},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, value := range zeroValues {
|
||||||
|
assert.Equal(true, IsZeroValue(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
var nonZeroIface fmt.Stringer = time.Now()
|
||||||
|
|
||||||
|
nonZeroValues := []interface{}{
|
||||||
|
// bool
|
||||||
|
true,
|
||||||
|
|
||||||
|
// int
|
||||||
|
1,
|
||||||
|
int8(1),
|
||||||
|
int16(1),
|
||||||
|
int32(1),
|
||||||
|
int64(1),
|
||||||
|
uint8(1),
|
||||||
|
uint16(1),
|
||||||
|
uint32(1),
|
||||||
|
uint64(1),
|
||||||
|
|
||||||
|
// float
|
||||||
|
1.0,
|
||||||
|
float32(1.0),
|
||||||
|
float64(1.0),
|
||||||
|
|
||||||
|
// string
|
||||||
|
"test",
|
||||||
|
|
||||||
|
// func
|
||||||
|
time.Now,
|
||||||
|
|
||||||
|
// array / slice
|
||||||
|
[]int{},
|
||||||
|
[]int{42},
|
||||||
|
[1]int{42},
|
||||||
|
|
||||||
|
// map
|
||||||
|
make(map[string]string, 1),
|
||||||
|
|
||||||
|
// interface
|
||||||
|
nonZeroIface,
|
||||||
|
|
||||||
|
// pointer
|
||||||
|
&nonZeroIface,
|
||||||
|
|
||||||
|
// struct
|
||||||
|
time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, value := range nonZeroValues {
|
||||||
|
assert.Equal(false, IsZeroValue(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user