go编程之代码控制技巧

目录

 

循环控制

条件控制

避免空指针

使用go开启协程是否传参注意

使用map应对函数中同时识别处理增删改都有可能的操作


循环控制

使用协程和通道跳出循环,满足跳出条件时让通道通信来通知goroutine

//...部分逻辑
done := false
go func() {
	<-chDone
	done = true
}()

//...部分逻辑
for !done {
    //...部分逻辑
    if 你的跳出循环的逻辑满足时{
        chData <- data    //data类型自定
    }
}

使用continue遍历时过滤数据

for _, value := range slice {
	if 某条件满足时 {
		continue    //直接进行下次循环,即对本次数据不作操作
	}
    //...操作value的逻辑,比如组装数据
	newSlice = append(newSlice, value)
}

条件控制

若条件较多,且每个条件下要执行逻辑代码也很多,可使用map+函数的方式,业务类型增加时只需增加对应的逻辑即可,原有的结构和逻辑不用动,比switch case好,如下:

/* 功能:根据传入的各种业务类型,执行不同的逻辑,逻辑写在不同的函数中 
    以下场景模拟单位解析转换
*/
const (
	AStr string = "A"
	BStr string = "B"
	//	很多业务类型...
)

//声明不同的类型对应的业务函数,使用map
var parseMap = map[string]func(inputType string) uint64{
	AStr: parseA,
	BStr: parseB,
}

func parseB(input string) uint64 {
    //解析B类型的逻辑,此处只简单返回
    if 你的操作input的逻辑{...}
	return 3
}

func parseA(input string) uint64 {
    //解析A类型的逻辑,此处只简单返回
	return 1
}

//使用
func TestTmp(t *testing.T) {
	//data为外界传入的变量,类型不固定,data.Type用来决定执行哪个函数
	if fun, ok := parseMap[data.Type]; ok {
        //这个函数就是fun,传入外界的待操作数据str
		ret := fun(str)
		fmt.Println(ret)
	}
}

减少else的使用,提高可读性

//...部分逻辑
if 满足某条件{
    return a
}else {
    return b
}

避免以上代码的出现,满足一种条件时return即可,如下:

if 满足某条件{
    return a
}
return b

if条件过多且每个条件下的逻辑不复杂时时考虑使用switch case

switch object {
	case "a":
		//逻辑1
	case "b":
		//逻辑2


避免if else嵌套多次多层,造成可读性差,难以维护。

避免空指针

对于x:= a.b.(string) 如果b是不是基本类型且没有设置过值的话,转类型会报空指针。处理如下:

if nil != a.b {
    x = a.b.(string)
}

使用go开启协程是否传参注意

//如果有变量i在协程中需要使用,值不确定,此时可传入匿名函数中
go func(i) {
    //操作i的逻辑
    //网络请求
}(i int)

//如果直接
go func() {
    //操作i的逻辑,直接使用i
    //网络请求
}()
那么数据将不准确,两者性质不同,注意细节

使用map应对函数中同时识别处理增删改都有可能的操作

业务场景:前端发送请求, 后端函数需要同时具备识别处理增删改某类型数据的功能

分析:传id的认为是修改操作,未传id的认为是新增的记录,有某记录但没传id的认为该记录需要删除。因为已创建的记录有id,因此后端先筛选新增和修改操作,其余的就是需要删除的数据了。

方案:使用map分别存储

//当前db中存在的数据:nowList
//接口传入的待操作数据:inputList

//将已有数据id全部存入map中
for i := range nowList.Data{
	oldMap[nowList.Data[i].ID] = i
}

//定义需要新增的和修改的map
var needAdd []model.ContainerSpec
var needUpdate []model.ContainerSpec

//遍历待操作的数据
forr i range inputList.Data{
    //如果ID值没有,则认为是需要新增的
    if len(data[i].ID) == 0 {
			needAdd = append(needAdd, data[i])
	} else {
        //否则认为进行修改
		needUpdate = append(needUpdate, data[i])
        //需要修改的数据在原有数据map中清除,剩余的就是需要删除的
		delete(oldMap, data[i].ID)
	}
}

//遍历needAdd、 oldMap等执行你的业务新增、删除操作即可...

不断的实践会不断的补充进来,总结来源于实践!

发布了155 篇原创文章 · 获赞 74 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/HYZX_9987/article/details/102976712