概要
在使用Golang开发中,标准库提供了很多好用的函数可以帮助我们快速的实现一些功能。但是相对于其他语言来说,还是有很多好用且常用的函数或者方法,是没有被加入到标准库的,这里就需要我们自己的来实现。
好用的函数
9. ArrayMerge 将任意多个切片合并成一个切片
源码
func ArrayMerge[T any](ss ...[]T) []T {
var result []T
for _, s := range ss {
result = append(result, s...)
}
return result
}
测试
func TestArrayMerge(t *testing.T) {
arr1 := []string{"A", "B", "C"}
arr2 := []string{"D", "E", "F"}
arr3 := []int{1, 2, 3}
arr4 := []int{4, 5, 6}
fmt.Println(ArrayMerge(arr1, arr2))
fmt.Println(ArrayMerge(arr3, arr4))
}
结果
=== RUN TestArrayMerge
[A B C D E F]
[1 2 3 4 5 6]
--- PASS: TestArrayMerge (0.00s)
PASS
10. ArrayChunk 将一个切片分割成多个切片
源码
func ArrayChunk[T any](s []T, size int) [][]T {
if size <= 0 {
return nil
}
var chunks [][]T
for i := 0; i < len(s); i += size {
end := i + size
if end > len(s) {
end = len(s)
}
chunks = append(chunks, s[i:end])
}
return chunks
}
测试
func TestArrayChunk(t *testing.T) {
a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
chunks := ArrayChunk(a, 3)
fmt.Println(chunks) // 输出 [[1 2 3] [4 5 6] [7 8 9]]
b := []string{"Hello", "world", "你好", "世界"}
chunks2 := ArrayChunk(b, 2)
fmt.Println(chunks2) // 输出 [[Hello world] [你好 世界]]
}
结果
=== RUN TestArrayChunk
[[1 2 3] [4 5 6] [7 8 9]]
[[Hello world] [你好 世界]]
--- PASS: TestArrayChunk (0.00s)
PASS
11. ArrayPad 将切片填充元素,并使总元素数达到固定个数
源码
func ArrayPad[T any](s []T, size int, val T) []T {
if size > 0 {
for i := len(s); i < size; i++ {
s = append(s, val)
}
} else if size < 0 {
for i := len(s); i < -size; i++ {
s = append([]T{val}, s...)
}
}
return s
}
说明
size: 表示填充完成后,最终的切片元素数量
测试
func TestArrayPad(t *testing.T) {
a := []int{1, 2, 3}
padded := ArrayPad(a, 5, 0)
fmt.Println(padded) // 输出 [1 2 3 0 0]
b := []string{"Hello", "world"}
padded2 := ArrayPad(b, -4, "你好")
fmt.Println(padded2) // 输出 [你好 你好 Hello world]
}
结果
=== RUN TestArrayPad
[1 2 3 0 0]
[你好 你好 Hello world]
--- PASS: TestArrayPad (0.00s)
PASS
12. ArrayRand 随机从原来切片中取N个元素,生成新的切片
源码
func ArrayRand[T any](s []T, n int) []T {
if n <= 0 || n > len(s) {
return nil
}
// 1.20之后,不需要这行
rand.Seed(time.Now().UnixNano())
rand.Shuffle(len(s), func(i, j int) { s[i], s[j] = s[j], s[i] })
return s[:n]
}
测试
func TestArrayRand(t *testing.T) {
a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
random := ArrayRand(a, 3)
fmt.Println(random) // 输出的结果会随机,例如 [7 2 1]
b := []string{"Hello", "world", "你好", "世界"}
random2 := ArrayRand(b, 2)
fmt.Println(random2) // 输出的结果会随机,例如 [你好 world]
}
结果
=== RUN TestArrayRand
[7 2 1]
[Hello 世界]
--- PASS: TestArrayRand (0.00s)
PASS
13. ArrayColumn 从元素为map的切片中,找到所有map指定的key对应的value值,并返回切片
源码
func ArrayColumn[T any, K comparable](maps []map[K]T, key K) []T {
var column []T
for _, m := range maps {
if val, ok := m[key]; ok {
column = append(column, val)
}
}
return column
}
测试
func TestArrayColumn(t *testing.T) {
maps := []map[string]interface{}{
{"name": "Alice", "age": 20},
{"name": "Bob", "age": 25},
{"name": "Charlie", "age": 30},
}
names := ArrayColumn(maps, "name")
fmt.Println(names) // 输出 [Alice Bob Charlie]
ages := ArrayColumn(maps, "age")
fmt.Println(ages) // 输出 [20 25 30]
}
结果
=== RUN TestArrayColumn
[Alice Bob Charlie]
[20 25 30]
--- PASS: TestArrayColumn (0.00s)
PASS
14. IsNumeric 判断一个元素是否为数值类型
源码
func IsNumeric(s any) bool {
switch v := s.(type) {
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64:
return true
case string:
_, err := strconv.ParseFloat(v, 64)
return err == nil
default:
return false
}
}
测试
func TestIsNumeric(t *testing.T) {
fmt.Println(IsNumeric("123")) // 输出 true
fmt.Println(IsNumeric("123.456")) // 输出 true
fmt.Println(IsNumeric(3.14)) // 输出 true
fmt.Println(IsNumeric("abc")) // 输出 false
fmt.Println(IsNumeric([]int{1, 2, 3})) // 输出 false
}
结果
=== RUN TestIsNumeric
true
true
true
false
false
--- PASS: TestIsNumeric (0.00s)
PASS
15. IsIP 判断一个字符串是否是IP地址
源码
func IsIP(ip string) bool {
return net.ParseIP(ip) != nil
}
测试
func TestIsIP(t *testing.T) {
fmt.Println(IsIP("192.168.1.1")) // 输出 true
fmt.Println(IsIP("2001:0db8:85a3:0000:0000:8a2e:0370:7334")) // 输出 true
fmt.Println(IsIP("not an ip address")) // 输出 false
}
结果
=== RUN TestIsIP
true
true
false
--- PASS: TestIsIP (0.00s)
PASS
16. RandomBytes 随机生成指定长度的字节数组
源码
func RandomBytes(len int) ([]byte, error) {
b := make([]byte, len)
_, err := rand.Read(b)
// 注意这里返回的n是读取的字节数
if err != nil {
return nil, err
}
return b, nil
}
测试
func TestRandomBytes(t *testing.T) {
fmt.Println(RandomBytes(10))
fmt.Println(RandomBytes(10))
fmt.Println(RandomBytes(10))
}
结果
=== RUN TestRandomBytes
[214 128 69 198 193 234 254 166 29 110] <nil>
[63 173 191 149 30 203 152 31 158 225] <nil>
[182 52 129 169 133 60 237 248 255 234] <nil>
--- PASS: TestRandomBytes (0.00s)
PASS
评论区