Go标准化
前言
最近将公司的一个项目代码进行初步的标准化,在过程中也有一些感悟和收获,进行简要的记录
项目代码注重标准化可以帮助我们写出高质量的代码
Go写法标准化
不要将
interface
做为万能的传递类型,不明确传递类型会降低代码的清晰度,interface
类型可以代表任意类型,编译器不知道参数会是什么类型,只有运行时才知道,因此**只能分配到堆上(增加GC压力)**;并且如果接收方也是interface
,则随意传递值会导致不可预估的后果(在twice中db层
就用interface接收control层
传的model是完全错误的)变量和函数命名规范,要有意义,看名知意且尽量简介,驼峰命名,动作+对象,不要在函数里创建大写开头的变量
error返回
- 关于
error
的原则是遇到err就进行判定err!=nil
而不是err==nil
,因为后者就会将正确包在括号里,一层一层如套娃一样,不美观也不优雅
1
2
3
4
5
6
7
8
9
10
11
12if err==nil{
if err==nil{
}else{}
}else{}
//修改为
if err!=nil{
}
if err!=nil{
}遇到
err
就要进行处理,而不是用匿名变量,唯一的对err
都不关心,除非对返回结果也不关心很多说go语言语法丑陋的,就是因为错误的返回方式,但是在代码风格上也可以进行优化避免大量的
if err!=nil
1
2
3
4
5
6
7
8err:=xxxFunction()
if err!=nil{
}
//修改为
if err:=xxxFunction();err!=nil{
}1
2
3
4
5
6
7
8
9
10
11func DBxxxOperate(xx model)error{
err:=DB.Create(&xx).Error
if err!=nil{
return err
}
return nil
}
//修改为
func DBxxxOperate(xx model)error{
return DB.Create(&xx).Error
}- 关于
对野生goroutine进行兜底保护
因为
gin
框架已经对每一个接口进行了兜底保护,即使发送panic也不会宕机(panic
),但是如果在接口中使用了野生goroutine并且在里面发升了panic
,那么整个程序都会崩溃!(包括主程序)1
2
3
4
5
6
7
8
9go func() {
defer func(){ //兜底保护
if err:=recover();err!=nil{
logger("happen panic!")
...
}
}
xxx()
}()
DB层标准化
返回时返回
error
而不是自定义的rsp
结构体(从而到control层
后直接作为数据返回给客户端),db层
只是完成数据库相关操作,如果在其他也需要该db层
返回的数据并且不需要rsp
这样重量级的返回,则需要返回到control会做进一步处理,并且会增加db层
的耦合度不要
在db层
做业务逻辑的操作,业务逻辑操作就该丢到control层
,db层
只用来做好数据库信息的操作即可,做到功能内聚比如对查询到的数据数组进行进一步的操作时,需要将返回至
control层
再操作,而不是在db层
操作后再返回给control层
在db层的操作只有对于Find操作时需要传递指针的(因为只返回error),其他关于Create、Update、Delete操作只需要传递值即可(如果不需要数据段Create和Update的时间信息),项目中尽量减少指针传递的操作,避免频繁的内存逃逸增加Go的GC压力最开始以为传入指针就会发生内存逃逸,后面发现并不是,具体请查看 Go逃逸分析详解
只有对于Find操作时需要传递指针的(因为要获取数据),其他关于Create、Update、Delete操作只需要传递值即可(如果不需要数据段Create和Update的时间信息),但是对于传值还是传指针,需要根据具体实际看(对于多字段的传值会有更多的
copy
操作)
Control层标准化
- 函数传递的值能少也要尽量少(前提是满足需求)
1 |
|
- 要相信一个原则:永远不要相信前端给你传来的值,则对于前端传来的值都需要进行验证,比如delete时需要验证delete_id是否存在,因为就算不存在delete空也不会报错,而对于update更要验证update_id的存在,因为不存在的话update会在数据库创建一个update_id的对象
Error返回标准化
对于API接口的调用返回也是非常重要的,对于返回最要使用同一的结构体进行封装(这样也是为了前端姿势同一和在进行测试时便利)
采用Code
和Data
的组合,没有加入消息和错误Message
Error
,因为对于发生错误时是并不需要前端和客户端知道具体是什么错误,只需要知道错误码,而后端则可以通过错误码来查看具体api逻辑值错误的地方,而消息Message则可以写在日志中,需要时则进行查看
更新:现在需要加入消息msg,因为这样前端在测试时才知道是自己出现了问题还是后端的问题
因为只要是有相应,则说明客户端和服务器相应成功,都应该是返回200,所以设置新的错误码才能有利于去区分不同的错误类型
1 |
|
对返回进行进一步封装,可分为成功有返回、成功无返回、错误(是为了在control
层写时清晰,知道是哪一种返回类型)
1 |
|
总结
在平时或工作中需要对自己代码进行严格的把控,对需要标准化的地方要仔细,这样才能写出高质量的代码
但是并不是在任何时候都要对代码标准化严格执行,在实际生产中,代码是需要在规定的时间进行产出,如果在任何时候任何地点严格把控代码就会大大拖慢项目进度
例如在error返回标准化时在项目最初是不需要对错误码进行规范等
但是在err优化操作、大小写字母命名这样的习惯则需要在任何时候养成
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!