【Golang】Golang超级实用的代码流
作者:mmseoamin日期:2024-04-29

【Golang】Golang超级实用的代码流

大家好 我是寸铁👊

总结了一篇【Golang】Golang超级实用的代码流✨

喜欢的小伙伴可以点点关注 💝


前言

本篇博文主要是把笔者开发中常用的一些处理函数整理总结成函数供大家去调用,便于后面有需要的小伙伴开发,后续会持续更新此贴,建议关注笔者,希望能帮助到大家💝


字符串

字符串与数字的相互转换

使用strconv包实现字符串与数字的相互转换

	//整数转字符串
    a := 123
	intToStr := strconv.Itoa(a)
	fmt.Printf("intToStr 类型为 %t\n", intToStr)
	//字符串转数字
	str := "123"
	strToInt, _ := strconv.Atoi(str)
	fmt.Printf("strToInt 类型为%t\n", strToInt)

运行结果如下:

intToStr 类型为 %!t(string=123)
strToInt 类型为%!t(int=123)

浮点数转换为字符串

import "strconv"
func main() {
    var f float32 = 3.14
    s := strconv.FormatFloat(float64(f), 'f', -1, 32)
    fmt.Println(s) // 输出: "3.14"
}

字符串分隔斜杆

常用于一些url或者配置文件的操作

func splitServiceName(str string) (ans string) {
	parts := strings.Split(str, "/") //得到的是分离掉斜杆的数组
	return parts[0]
}

字符串分离 _

func separateAlphaNumber(str string) []string {
	// 使用 strings 包中的 Split 函数按照下划线 "_" 分割字符串
	idParts := strings.Split(str, "_")
	return idParts
}

将域名进行分隔处理

func splitLastPart(ipAddress string) string {
	// 使用 strings 包的 Split 函数将 IP 地址按照 "." 进行分割
	parts := strings.Split(ipAddress, ".")
	// 获取切片中最后一个元素(即最后的部分)
	lastPart := parts[len(parts)-1] // 127.0.0.72 --> 72
	return lastPart
}

判断取出的值是否全部都是数字

/*
作用: 判断取出的值是否全部都是数字
*/
func judgeAllAlapha(strs string) bool {
	// 判断字符串数组中的所有字符串是否都是数字
	allDigits := true
	for _, char := range strs {
		if !unicode.IsDigit(char) {
			allDigits = false
			break
		}
	}
	return allDigits
}

移除掉字符串的第一个斜杠

func removeFirstSlash(input string) string {
	if strings.HasPrefix(input, "/") {
		return input[1:]
	}
	return input
}

将多个字符串拼接成一个新的字符串

// ConcatenateStrings 将多个字符串拼接成一个新的字符串
func ConcatenateStrings(strs ...string) string {
    return strings.Join(strs, " ")
}

返回给定字符串的长度

// GetStringLength 返回给定字符串的长度
func GetStringLength(str string) int {
    return len(str)
}

根据指定分隔符将字符串分割为多个子字符串

// SplitString 根据指定分隔符将字符串分割为多个子字符串
func SplitString(str, sep string) []string {
    return strings.Split(str, sep)
}

子字符串是否存在于主字符串中

// CheckSubstring 子字符串是否存在于主字符串中
func CheckSubstring(str, substr string) bool {
    return strings.Contains(str, substr)
}

替换主字符串中的子字符串为新的字符串

// ReplaceSubstring 替换主字符串中的子字符串为新的字符串
func ReplaceSubstring(str, old, new string) string {
    return strings.Replace(str, old, new, -1)
}

接口转换为字符串

func interToStr(inter interface{})(str string){
return inter.(string)
}

移除切片第一个元素中的斜杠

func splitStrSlice(stringArray []string) string {
	// 移除第一个元素中的斜杠
	if len(stringArray) > 0 {
		firstElement := stringArray[0]
		if strings.HasPrefix(firstElement, "/") {
			stringArray[0] = firstElement[1:]
		}
	}
	return stringArray[0]
}

数组

判断切片中元素是否存在

func contains(elems []string, v string) bool {
    for _, s := range elems {
        if v == s {
            return true
        }
    }
    return false
}

切片的深拷贝

最常用的copy方法如下:

copy(dest, src)

代码示例:

var currentServicesSlice = []string{}
var lastServiceSlice = []string{}
//初始化map
currentServicesSlice = make([]string, 0)
lastServiceSlice = make([]string, 0)
//切片的深拷贝
lastServiceSlice = make([]string, len(currentServicesSlice))
		copy(lastServiceSlice, currentServicesSlice)

注意:lastServiceSlice 待赋值的切片的容量要和赋值的切片的容量一致,所以,要先进行重新的初始化,对切片的容量进行扩容,确保将元素准确无漏的拷贝到要赋值的切片currentServicesSlice。


对整数数组进行排序

返回从小到大的有序数组

func numberSort(numbers []int) []int {
	sort.Ints(numbers)
	return numbers
}

获取有序数组中不连续的数字

func getDbIdx(indexsMap map[string][]int, idx int, name string) (index int) {
	//根据名字查找出映射出的切片 再进行索引更新操作
	ints := indexsMap[name]
	for i := 1; i <= ints[len(ints)-1]; i++ {
		if !isNumberInSlice(i, ints) {
			return i
		}
	}
	return idx + 1
}

计算切片中所有元素的和

// SumSlice 计算切片中所有元素的和
func SumSlice(slice []int) int {
	sum := 0
	for _, value := range slice {
		sum += value
	}
	return sum
}

计算切片中所有元素的平均值

// AverageSlice 计算切片中所有元素的平均值
func AverageSlice(slice []int) float64 {
	sum := SumSlice(slice)
	average := float64(sum) / float64(len(slice))
	return average
}

将切片中的元素顺序反转

// ReverseSlice 将切片中的元素顺序反转
func ReverseSlice(slice []int) {
	for i, j := 0, len(slice)-1; i < j; i, j = i+1, j-1 {
		slice[i], slice[j] = slice[j], slice[i]
	}
}

切片元素去重

// RemoveDuplicates 从切片中移除重复的元素,并返回新的切片
func RemoveDuplicates(slice []int) []int {
	encountered := make(map[int]bool)
	result := []int{}
	for _, value := range slice {
		if !encountered[value] {
			encountered[value] = true
			result = append(result, value)
		}
	}
	return result
}

添加元素到切片

func AppendToSlice(slice []int, element int) []int {
    return append(slice, element)
}

合并多个切片

func MergeSlices(slice1, slice2 []int) []int {
    return append(slice1, slice2...)
}

返回切片的索引

func FindInSlice(slice []int, target int) int {
    for index, value := range slice {
        if value == target {
            return index
        }
    }
    return -1 // 表示找不到
}

切片截取

//截取切片中的一部分元素,生成一个新的切片。
func SliceSubslice(slice []int, start, end int) []int {
    return slice[start:end]
}

map

判断map的值是否为空

注意不是用nil来进行判断!!!

正确做法如下:

if len(map[key]) == 0{
fmt.Println("值为空……")
}

检查指定的键是否存在于 Map 中

// CheckKeyExists 检查指定的键是否存在于 Map 中
func CheckKeyExists(m map[string]int, key string) bool {
	_, exists := m[key]
	return exists
}

根据键获取 Map 中的值,如果键不存在返回零值

// GetValueByKey 根据键获取 Map 中的值,如果键不存在返回零值
func GetValueByKey(m map[string]int, key string) int {
	return m[key]
}

从 Map 中移除指定的键及其对应的值

// RemoveKey 从 Map 中移除指定的键及其对应的值
func RemoveKey(m map[string]int, key string) {
	delete(m, key)
}

遍历 Map 并对其中的键值对进行操作

func IterateMap(m map[string]int) {
	for key, value := range m {
		fmt.Printf("Key: %s, Value: %d\n", key, value)
	}
}

获取 Map 中所有键的集合

func GetKeys(m map[string]int) []string {
	keys := make([]string, 0, len(m))
	for key := range m {
		keys = append(keys, key)
	}
	return keys
}

获取 Map 中所有值的集合

func GetValues(m map[string]int) []int {
	values := make([]int, 0, len(m))
	for _, value := range m {
		values = append(values, value)
	}
	return values
}

计算 Map 的长度

func MapLength(m map[string]int) int {
	return len(m)
}

Time

测试程序运行时间

  • 计算代码块的运行时间
    start := time.Now()
    //some func or operation
    cost := time.Since(start)
    fmt.Printf("cost=[%s]",cost)
    

    其中time.Since()函数返回字符串类型,时间格式例如1h2m3s等。

    • 计算函数的运行时间
      func testFuncTime() {
          start := time.Now()
          defer func() {
              cost := time.Since(start)
              fmt.Println("cost=", cost)
          }()
          // 逻辑部分
      }
      

      函数启动开始定时,之后使用defer待整个函数结束后,计算出差值时间。


      字符串转换为时间

      startTime := "2024/04/14 15:50:20"
      configTime, err := time.Parse("2006/01/02 15:04:05", startTime)
      	if err != nil {
      		fmt.Println("解析时间字符串时出错:", err)
      		return
      	}
      

      时间转换为字符串

      // 获取现在的时间
      currentTime := time.Now()
      // 将时间格式化为字符串
      timeStr := currentTime.Format("2006/01/02 15:04:05")
      fmt.Println("timeStr: ", timeStr)
      

      CST与UTC时区对齐

      小知识: 时区存在差值

      • CST要转换为UTC时区需要加上8个小时
      • UTC要转换为CST时区需要减去8个小时
        startTime := "2024/04/14 15:50:20"
        configTime, err := time.Parse("2006/01/02 15:04:05", startTime)
        	if err != nil {
        		fmt.Println("解析时间字符串时出错:", err)
        		return
        	}
        //configTime处理后为UTC时区	
        nowTime := time.Now(); //获取的是CTS时区
        //CST要转换为UTC时区需要加上8个小时,这样时间就对齐了。
        utcTime := nowTime.UTC().Add(8 * time.Hour)
        fmt.Println("utcTime: ", utcTime)
        fmt.Println("configTime: ", configTime)
        //计算时间差
        sleepTime := configTime.Sub(utcTime)
        fmt.Println("sleepTime: ", sleepTime)
        

        输出结果如下:

        这样时间就对齐了

        time:  2024/04/14 15:50:20
        utcTime:  2024-04-14 15:20:34.9206904 +0000 UTC
        configTime:  2024-04-14 15:50:20 +0000 UTC
        sleepTime:  29m45.0793096s
        

        获取时间差的分钟数和秒数

        		completeTime, err := time.Parse("2006-01-02 15:04:05", completetime.(string))
        			if err != nil {
        				fmt.Println("解析 completeTime 错误:", err)
        				return
        			}
        			fmt.Println("completeTime: ", completeTime)
        			startTime, err := time.Parse("2006-01-02 15:04:05", starttime.(string))
        			if err != nil {
        				fmt.Println("解析 startTime 错误:", err)
        				return
        			}
        			fmt.Println("startTime: ", startTime)
        			// 计算时间差值
        			timeDifference := completeTime.Sub(startTime)
        			total += int(timeDifference.Seconds())
        			// 打印时间差值
        			fmt.Println("completeTime 和 startTime 的时间差值:", timeDifference)
        			//得到平均的分钟数
        			minutes := total / (60 * len(allTaskID)) // 将秒数除以60得到分钟数 再除以总的任务数得到平均分钟数
        			//fmt.Println("minutes: ", minutes)
        			//得到平均的秒数
        			remainingSeconds := (total % 60) / len(allTaskID) //%60计算剩余的秒数 再除以总的任务数得到平均秒数
        			fmt.Printf("平均值为: %dm%ds", minutes, remainingSeconds)
        

        文件处理

        读取指定路径的文件内容并返回字节切片
        // ReadFile 读取指定路径的文件内容并返回字节切片
        func ReadFile(filePath string) ([]byte, error) {
        	content, err := ioutil.ReadFile(filePath)
        	if err != nil {
        		return nil, err
        	}
        	return content, nil
        }
        

        读取指定路径的文件内容并返回字符串
        // ReadFileToString 读取指定路径的文件内容并返回字符串
        func ReadFileToString(filePath string) (string, error) {
        	content, err := ReadFile(filePath)
        	if err != nil {
        		return "", err
        	}
        	return string(content), nil
        }
        

        读取指定路径的文件内容并按行返回字符串切片
        // ReadFileLines 读取指定路径的文件内容并按行返回字符串切片
        func ReadFileLines(filePath string) ([]string, error) {
        	content, err := ReadFileToString(filePath)
        	if err != nil {
        		return nil, err
        	}
        	lines := splitLines(content)
        	return lines, nil
        }
        
        按行拆分字符串并返回字符串切片
        // splitLines 按行拆分字符串并返回字符串切片
        func splitLines(content string) []string {
        	var lines []string
        	start := 0
        	for i := 0; i < len(content); i++ {
        		if content[i] == '\n' {
        			lines = append(lines, content[start:i])
        			start = i + 1
        		} else if i == len(content)-1 {
        			lines = append(lines, content[start:])
        		}
        	}
        	return lines
        }
        
        测试函数
        func main() {
        	filePath := "example.txt"
        	// 读取整个文件内容
        	content, err := ReadFile(filePath)
        	if err != nil {
        		fmt.Println("Error reading file:", err)
        		return
        	}
        	fmt.Println("File content:")
        	fmt.Println(string(content))
        	// 读取文件内容并转换为字符串
        	fileContent, err := ReadFileToString(filePath)
        	if err != nil {
        		fmt.Println("Error reading file:", err)
        		return
        	}
        	fmt.Println("File content as string:")
        	fmt.Println(fileContent)
        	// 按行读取文件内容
        	lines, err := ReadFileLines(filePath)
        	if err != nil {
        		fmt.Println("Error reading file:", err)
        		return
        	}
        	fmt.Println("File content by lines:")
        	for _, line := range lines {
        		fmt.Println(line)
        	}
        }
        

        看到这里的小伙伴,恭喜你又掌握了一个技能👊

        希望大家能取得胜利,坚持就是胜利💪

        我是寸铁!我们下期再见💕


        往期好文💕

        保姆级教程

        【保姆级教程】Windows11下go-zero的etcd安装与初步使用

        【保姆级教程】Windows11安装go-zero代码生成工具goctl、protoc、go-zero

        【Go-Zero】手把手带你在goland中创建api文件并设置高亮


        报错解决

        【Go-Zero】Error: user.api 27:9 syntax error: expected ‘:‘ | ‘IDENT‘ | ‘INT‘, got ‘(‘ 报错解决方案及api路由注意事项

        【Go-Zero】Error: only one service expected goctl一键转换生成rpc服务错误解决方案

        【Go-Zero】【error】 failed to initialize database, got error Error 1045 (28000):报错解决方案

        【Go-Zero】Error 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)报错解决方案

        【Go-Zero】type mismatch for field “Auth.AccessSecret“, expect “string“, actual “number“报错解决方案

        【Go-Zero】Error: user.api 30:2 syntax error: expected ‘)‘ | ‘KEY‘, got ‘IDENT‘报错解决方案

        【Go-Zero】Windows启动rpc服务报错panic:context deadline exceeded解决方案


        Go面试向

        【Go面试向】defer与time.sleep初探

        【Go面试向】defer与return的执行顺序初探

        【Go面试向】Go程序的执行顺序

        【Go面试向】rune和byte类型的认识与使用

        【Go面试向】实现map稳定的有序遍历的方式