【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)
判断字符串内容是否为数字
// 判断字符是否能转为整数
func isInteger(s string) (judgeNumber bool, nums int) {
//将字符串进行转换为整数
num, err := strconv.Atoi(s)
return err == nil, num //err为nil则说明为整数 err不为nil则说明不为整数
浮点数转换为字符串
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 isInteger(s string) bool {
//将字符串进行转换为整数
_, err := strconv.Atoi(s)
return err == nil //err为nil则说明为整数 err不为nil则说明不为整数
}
移除掉字符串的第一个斜杠
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
}
获得有序数组缺失的连续值
场景: 常用于字符串命名编号的更新,需要获取最小缺失的连续值(
第一个连续数组的空缺值
)来进行命名。
数组[1,4,2,7]
求缺失的连续值,
原数组[1,4,2,7]
排序数组[1,2,4,7]
则缺失的连续值数组[3,5,6]
func getNewestNum(arr []int) int {
// 数组排序
sort.Ints(arr)
// 查找不连续的值
var disContinuousValues []int //存储的是不连续编号的数组
for i := 1; i < len(arr); i++ {
//如果说当前的数比上一个数不连续
if arr[i]-arr[i-1] > 1 {
//则把上一个的下一个数到当前的数的前一个都添加到不连续数组中missingValues
for j := arr[i-1] + 1; j < arr[i]; j++ {
disContinuousValues = append(disContinuousValues, j)
}
}
}
// 如果没有不连续的值,说明当前数组中是连续的,则直接返回最后一个元素加 1
if len(disContinuousValues) == 0 {
return arr[len(arr)-1] + 1
}
// 如果有连续且缺失的值,则返回第一个数即可
return disContinuousValues[0]
}
切片的深拷贝
最常用的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解决方案