官方编码规范:https://github.com/golang/go/wiki/CodeReviewComments
一、命名
- 文件名全小写
- package 名字:包名与目录保持一致,尽量有意义,简短,不和标准库冲突, 全小写,不要有下划线
- 变量名采用驼峰法,不要有下划线,不要全部大写 命名
var ( GetInfo bool // 包外可见 getInfo bool // 包内可见 )
二、格式
- ide设置自动格式化
- 每行长度约定: 一行不要太长,超过请使用换行展示,尽量保持格式优雅;单个文件也不要太大,最好不要超过500行
- struct新对象/声明采用多行,更加一目了然 格式
p := &StructName{ field1: 1, field2: "aaaa", }
三、 import 规范
//建议采用如下格式:
import (
"fmt"
)
//如果你的包引入了三种类型的包,标准库包,程序内部包,第三方包,建议采用如下方式进行组织你的包:
import (
encoding/json"
"strings"
"myproject/models"
"myproject/controller"
"myproject/utils"
"github.com/astaxie/beego"
"github.com/go-sql-driver/mysql"
)
//有顺序的引入包,不同的类型采用空格分离,第一种实标准库,第二是项目包,第三是第三方包。
//在项目中不要使用相对路径引入包:
//import "../net" // 这是不好的导入
//import "github.com/repo/proj/src/net" // 这是正确的做法
四、数据类型使用、 函数
- 函数的多返回值最多返回三个,超过三个请使用 struct
- 参数传递。 对于少量数据,不要传递指针; 对于大量数据的 struct 可以考虑使用指针, 值拷贝;传入参数是 map,slice,chan,interface,string 不要传递指针, 引用类型
- golang的内置类型slice,map,chan都是引用,初次使用前,都必须先用make分配好对象,不然会有空指针异常
- 使用map时需要注意:map初次使用,必须用make初始化;map是引用,不用担心赋值内存拷贝;并发操作时,需要加锁;range遍历时顺序不确定,不可依赖;不能使用slice,map和func作为key
五、逻辑分支
- 不要忽略 error,每个 error 都必须处理,实在不用处理,就打印 error。有 错误尽早返回
//不要这样写: if err != nil { // error handling } else { // normal code } //而应该是: if err != nil { // error handling return // or continue, etc. } // normal code
- 不要在for循环里面使用defer,defer只有在函数退出时才会执行 逻辑分支
六、基础库
- 每个基础库都必须有实际可运行的例子, 基础库的接口都要有单元测试用例
七、go特性使用规范
- 竞态检测。 多协程的竞争问题暴露。 go build –race (测试环境编译时加上 -race 选项,生产环境必须去掉,因为race限制最多goroutine数量为8192个)
- 时刻提醒自己 goroutine 的生命周期,注意同步 channel,防止 goroutine 堵住,释放不了,出现内存泄漏
- 注意关闭 channel 问题,不能 close 两次,不能向 closed 的 chan 写入数据
- 禁止在业务代码里面调用cgo。 一般密集计算的逻辑可以放cgo,这样一次的调用成本可以接受