- 变量
- 变量越重要,生存周期越长,变量名越长
- 变量名不应该包含类型信息
- 变量名应该和默认值相符合
- 例如
isCacheDsiabled
要比isCacheEnabled
好,因为默认值是false
- 例如
- 首字母应该默认小写,尽量减少作用域
- 变量的分组声明也可以用在函数内部
- 非导出的全局变量应该以下划线开头
- 避免与函数内部变量重名导致不可预料的bug
- 结构体的嵌入类型(例如mutex)应该放在开头,且和常规字段分开
- 用于格式化的字符串应该放在printf外面,并用const修饰
- 尽量利用
type
创建新的具体的类型代替宽泛的[]int
等基本类型- 好处是可以自定义新方法
- 函数
- 函数不应该超过50行
- 一个函数应该只做一件事
- 使用接口参数让函数自己定义它所需要的行为
- 如果你的函数开启了一个协程,应该返回个调用者一个关闭协程的函数
- 尽量不使用命名返回值
- 如果要忽略返回值,应该使用
_ = f()
显示指出 - 把 for-select 语句换成一个函数
- 方法
- 如果不清楚使用值接受者还是指针接受者,使用指针接受者
- 并发
- 以线程安全的方式创建一些东西的最好选择是
sync.Once
- 例如配置的初始化
- 以线程安全的方式创建一些东西的最好选择是
- 网络
- 总是关闭http的body:
defer r.Body.Close()
- 应该先检查 HTTP 响应错误为 nil,再调用 resp.Body.Close() 来关闭响应体
- 总是关闭http的body:
- init函数
- 不要在init函数中执行初始化等操作
- 如果另一个 package 依赖了当前的包,那么引入这个依赖的工程师可能会在遇到错误时非常困惑
- 们不应该在 init 中做过重的初始化逻辑,而是做一些简单的前置条件判断
- 不要在init函数中执行初始化等操作
- 错误处理
- 向上抛出错误时可以通过 errors.Wrap 携带一些额外的信息方便上层进行判断
- 其他
- 多个if语句考虑用switch代替
- 用 chan struct{} 来传递信号, chan bool 表达的不够清楚
- 每个阻塞或者 IO 函数操作应该是可取消的或者至少是可超时的
- 如果你要比较时间戳,请使用
time.Before
或time.After
,不要使用time.Sub
来获得 duration ,然后检查它的值 - 不要忘记停止 ticker
ticker := time.NewTicker(1 * time.Second); defer ticker.Stop()
- 判断slice为空时,判断长度而不是nil
- 从slice中切出新slice时,重新声明新slice并拷贝旧slice
copy(new, old)
- 否则旧底层大数组不会释放,造成内存超标
golang 代码规范
猜你喜欢
转载自blog.csdn.net/winter_wu_1998/article/details/102926479
今日推荐
周排行