概要
在使用Golang开发中,标准库提供了很多好用的函数可以帮助我们快速的实现一些功能。但是相对于其他语言来说,还是有很多好用且常用的函数或者方法,是没有被加入到标准库的,这里就需要我们自己的来实现。
好用的函数
1. Implode 将任意类型数组,按照分割符,转成字符串
源码
func Implode[T any](arr []T, delimiter string) string {
var result string
for i, v := range arr {
if i > 0 {
result += delimiter
}
result += fmt.Sprintf("%v", v)
}
return result
}
测试
func TestImplode(t *testing.T) {
arr1 := []string{"A", "B", "C"}
arr2 := []int{1, 2, 3}
arr3 := []interface{}{1, "B", 3}
fmt.Println(Implode(arr1, ","))
fmt.Println(Implode(arr2, ","))
fmt.Println(Implode(arr3, ","))
}
结果
=== RUN TestImplode
A,B,C
1,2,3
1,B,3
--- PASS: TestImplode (0.00s)
PASS
2. InSlice 判断一个元素,是否包含在一个切片内
源码
func InSlice[T comparable](need T, arr []T) bool {
for _, v := range arr {
if v == need {
return true
}
}
return false
}
测试
func TestInSlice(t *testing.T) {
arr1 := []string{"A", "B", "C"}
arr2 := []int{1, 2, 3}
arr3 := []interface{}{1, "B", 3}
fmt.Println(InSlice("A", arr1))
fmt.Println(InSlice(2, arr2))
// []interface{} 类型的需要go1.20以上版本
fmt.Println(InSlice(3, arr3))
}
结果
=== RUN TestInSlice
true
true
true
--- PASS: TestInSlice (0.00s)
PASS
3. Empty 判断一个变量,是否为空值
源码
// EmptyInterface 定义Empty接口
type EmptyInterface interface {
IsEmpty() bool
}
type MyString string
type MyInt int
type MySlice []int
func (s MyString) IsEmpty() bool {
return s == ""
}
func (i MyInt) IsEmpty() bool {
return i == 0
}
func (sl MySlice) IsEmpty() bool {
return len(sl) == 0
}
func Empty[T EmptyInterface](val T) bool {
return val.IsEmpty()
}
说明
在这个示例中,我们首先定义了一个名为EmptyInterface的接口,该接口包含一个名为IsEmpty的方法。然后,我们为MyString、MyInt和MySlice类型定义了IsEmpty方法,使它们满足EmptyInterface接口。最后,我们定义了一个泛型函数Empty,该函数接受一个满足EmptyInterface接口的参数,并调用其IsEmpty方法来判断它是否为空。
这种方法的优点是避免了反射的使用,提高了性能。但是,它需要为每种需要检查是否为空的类型定义一个满足EmptyInterface接口的方法,这可能会增加代码的复杂性。
测试
func TestEmpty(t *testing.T) {
fmt.Println(Empty(MyString(""))) // true
fmt.Println(Empty(MyString("hello"))) // false
fmt.Println(Empty(MyInt(0))) // true
fmt.Println(Empty(MyInt(42))) // false
fmt.Println(Empty(MySlice{})) // true
fmt.Println(Empty(MySlice{1, 2})) // false
}
结果
=== RUN TestEmpty
true
false
true
false
true
false
--- PASS: TestEmpty (0.00s)
PASS
4. Strpos 判断一个字符串在另一个字符串的首次出现的位置
源码
func Strpos(haystack, needle string, offset int) int {
length := len(haystack)
if length == 0 || offset > length || -offset > length {
return -1
}
if offset < 0 {
offset += length
}
pos := strings.Index(haystack[offset:], needle)
if pos == -1 {
return -1
}
return pos + offset
}
说明
haystack
为查找之所在的字符串,needle
为要查找的字符串,offset
为偏移量,当offset
设置为0的时候,则从头开始查找。
测试
func TestStrpos(t *testing.T) {
str := "abcdsj1dhakadk"
fmt.Println(Strpos(str, "d", 0))
fmt.Println(Strpos(str, "1", 0))
fmt.Println(Strpos(str, "a", 2))
}
结果
=== RUN TestStrpos
3
6
9
--- PASS: TestStrpos (0.00s)
PASS
5. Ucfirst 将字符串首字母大写
源码
func Ucfirst(s string) string {
if len(s) == 0 {
return s
}
firstRune := []rune(s)[0]
if unicode.IsLower(firstRune) {
firstRune = unicode.ToUpper(firstRune)
}
return string(firstRune) + s[1:]
}
测试
func TestUcfirst(t *testing.T) {
fmt.Println(Ucfirst("hello"))
fmt.Println(Ucfirst("i am lisi"))
fmt.Println(Ucfirst("34"))
}
结果
=== RUN TestUcfirst
Hello
I am lisi
34
--- PASS: TestUcfirst (0.00s)
PASS
6. Substr 切割字符串
源码
func Substr(str string, start uint, length int) string {
runes := []rune(str)
strLen := len(runes)
if start >= uint(strLen) {
return ""
}
if length < 0 || int(start)+length > strLen {
length = strLen - int(start)
}
return string(runes[start : start+uint(length)])
}
说明
str
为要切割的目标字符串,start
为切割的起始位置,length
为切割的长度
测试
func TestSubstr(t *testing.T) {
str := "abcdefghijklmn"
fmt.Println(Substr(str, 0, 3))
fmt.Println(Substr(str, 1, 3))
fmt.Println(Substr(str, 1, -1))
}
结果
=== RUN TestSubstr
abc
bcd
bcdefghijklmn
--- PASS: TestSubstr (0.00s)
PASS
7. Strrev 翻转字符串
源码
func Strrev(str string) string {
runes := []rune(str)
runesLen := len(runes)
for i := 0; i < runesLen/2; i++ {
runes[i], runes[runesLen-1-i] = runes[runesLen-1-i], runes[i]
}
return string(runes)
}
测试
func TestStrrev(t *testing.T) {
fmt.Println(Strrev("abcd"))
fmt.Println(Strrev("hi abc"))
fmt.Println(Strrev("123456"))
}
结果
=== RUN TestStrrev
dcba
cba ih
654321
--- PASS: TestStrrev (0.00s)
PASS
8. StrShuffle 随机打乱一个字符串
源码
func StrShuffle(str string) string {
runes := []rune(str)
runesLen := len(runes)
// 1.20以后,不需要此行代码
rand.Seed(time.Now().UnixNano())
for i := runesLen - 1; i > 0; i-- {
j := rand.Intn(i + 1)
runes[i], runes[j] = runes[j], runes[i]
}
return string(runes)
}
测试
func TestStrShuffle(t *testing.T) {
fmt.Println(StrShuffle("abcdefg"))
fmt.Println(StrShuffle("hello world"))
fmt.Println(StrShuffle("i am zhangsan"))
}
结果
=== RUN TestStrShuffle
afdebgc
oelroldwhl
mzn niaga ahs
--- PASS: TestStrShuffle (0.00s)
PASS
评论区