Go代码规范梳理
Go代码规范(Code Review)
总结几个开发过程中经常会犯的代码规范错误
注释语句
// Request 表示运行命令的请求。
type Request struct { ...
// Encode 将 req 的 JSON 编码写入 w 。
func Encode(w io.Writer, req *Request) { ...
上下文
大部分使用上下文的函数都要将其作为第一个参数
func F(ctx context.Context, /* 其他参数 */) {}
不建议把上下文作为成员添加到结构类型中
// 不建议写法
type MyContext struct {
ctx context.Context
}
Crypto Rand
不要使用 math/rand
来生成密钥,即使是一次性密钥。在没有种子(seed)的情况下,生成器是完全可以被预测的。请使用 crypto/rand
的 Reader 作为替代
func Key() string {
buf := make([]byte, 16)
_, err := rand.Read(buf)
if err != nil {
panic(err) // 出于随机性,永远都不会发生
}
return fmt.Sprintf("%x", buf)
// or hex.EncodeToString(buf)
// or base64.StdEncoding.EncodeToString(buf)
}
func main() {
fmt.Println(Key())
}
//输出
//4799b801e7866209593cfaedb03cf8da
声明空的切片
当声明一个空 slice 时,倾向于用
var t []string
而不是
t := []string{}
前者声明了一个 nil slice 值,而后者声明了一个非 nil 但是零长度的 slice。两者在功能上等同,len 和 cap 均为零,而 nil slice 是首选的风格。
请注意,在部分场景下,首选非 nil 但零长度的切片,例如编码 JSON 对象时(nil 切片编码为 null
,而则 []string{}
可以正确编码为 JSON array []
)。
包注释
/*
Package template implements data-driven templates for generating textual
output such as HTML.
....
*/
package template
如果包很简单,包注释可以很简短。
// Package math provides basic constants and mathematical functions.
package math
包名
对包中名称的所有引用都将使用包名完成,因此可以从标识符中省略该名称。 例如,如果你正在使用 chubby
包,则不需键入 ChubbyFile
,因为客户端会将其写为 chubby.ChubbyFile
。 相反,命名为 File
的这种方式,客户端会将它写为 chubby.File
。 避免使用像 util
、 common
、 misc
、 api
、 types
和 interfaces
这样无意义的包名。
不要Panic
错误信息
即使用 fmt.Errorf("something bad")
而不要使用 fmt.Errorf("Something bad")
包的导入
避免包重命名导入,防止名称冲突;好的包名称不需要重命名。如果发生命名冲突,则更倾向于重命名最接近本地的包或特定于项目的包。
包导入按组进行组织,组与组之间有空行。标准库包始终位于第一组中。
package main
import (
"fmt"
"hash/adler32"
"os"
"appengine/foo"
"appengine/user"
"github.com/foo/bar"
"rsc.io/goversion/version"
)
包的匿名导入
即 import _ "pkg"
这种导入语句,最好只存在于main.go文件中
Dot 导入
package foo_test
import (
. "foo"
)
不要在程序中使用 import .
。它将使程序更难阅读
内联错误
不规范写法
// 查找返回键的值,如果没有键的映射,则返回空字符串。
func Lookup(key string) string
规范写法
// 查找并返回键的值,如果没有键的映射,则ok = false。
func Lookup(key string) (value string, ok bool)
并有利于写出更健壮和可读性更强的代码:
value, ok := Lookup(key)
if !ok {
return fmt.Errorf("no value for %q", key)
}
return Parse(value)
缩进错误处理
要缩进错误处理逻辑,不要缩进常规代码。这样可以改进代码的可读性,读者可以快速地浏览逻辑主干。例如,不要写:
if x, err := f(); err != nil {
// 错误处理
return
} else {
// 使用变量 x
}
相反,应该这样写:
x, err := f()
if err != nil {
// 错误处理
return
}
// 使用变量 x
这样写的好处可以增加可读性
首字母缩写
名称中的单词是首字母或首字母缩略词(例如 "URL" 或 "NATO" )需要具有相同的大小写规则。例如,"URL" 应显示为 "URL" 或 "url" (如 "urlPony" 或 "URLPony" ),而不是 "Url"。举个例子:ServeHTTP 不是 ServeHttp。对于具有多个初始化 “单词” 的标识符,也应当显示为 "xmlHTTPRequest" 或 "XMLHTTPRequest"。
当 "ID" 是 "identifier" 的缩写时,此规则也适用于 "ID" ,因此请写 "appID" 而不是 "appId"。
protocol buffer 生成的代码是个例外,对人和对机器的要求不能一样,人编写的代码要比机器编写的代码保持更高的标准。
接口
总的来说,Go 的接口要包含在使用方的包里,不应该包含在实现方的包里。实现方只需要返回具体类型(通常是指针或结构体),这样一来可以将新方法添加到实现中,而不需要扩展重构。
不要在 API 的实现者端定义 "for mocking" 接口;反而是要定义公开的 API,用真实的实现进行测试。
不要先定义接口再用它。脱离真实的使用场景,我们都不能确定一个接口是否有存在的价值,更别提设计接口的方法了
建议写法,把接口和接口具体的实现类分开两个go文件
package consumer // consumer_func.go
type Thinger interface { Thing() bool }
func Foo(t Thinger) string { … }
package consumer //consumer.go
type defaultThinger struct{ … }
func (t defaultThinger) Thing() bool { … }
func NewThinger() Thinger { return defaultThinger{ … } }
不规范写法
package producer
type Thinger struct{ … }
func (t Thinger) Thing() bool { … }
func NewThinger() Thinger { return Thinger{ … } }
方法接收者命名
方法接收者的名称应该反映其身份;通常,其类型的一个或两个字母缩写就足够了(例如用 "c" 或 "cl" 表示 "client" )。不要使用通用名称,例如 "me","this" 或 "self",这是面向对象语言的典型标识符,这些标识符赋予该方法特殊的含义。
方法接收者类型
要是把握不准,就用指针。
变量名称
Go 中的变量名称尽可能短为妙,言简意赅,尤其是对于那些处于有限空间中的局部变量更是如此。例如: 用 c 而不是 lineCount
; 用 i
而不是 sliceIndex
。
基本准则:当变量首次被使用时离声明的位置越远,变量名称必须更具描述性。对于方法接收者的名称来说,一个或者两个字母就足够了。普通变量比如 loop indices
、 readers
的名称用一个字母(i
, r
)指代就可以。
当然,对于一些逻辑比较复杂的逻辑,或者非常规事物,或者全局变量则需使用更具描述性的名字。
Go代码规范梳理的更多相关文章
- Scrum立会报告+燃尽图(十一月十五日总第二十三次):代码规范与技术交流
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2384 项目地址:https://git.coding.net/zhang ...
- iOS代码规范(OC和Swift)
下面说下iOS的代码规范问题,如果大家觉得还不错,可以直接用到项目中,有不同意见 可以在下面讨论下. 相信很多人工作中最烦的就是代码不规范,命名不规范,曾经见过一个VC里有3个按钮被命名为button ...
- 谈谈PHP代码规范
[转] http://www.syyong.com/php/Talk-about-PHP-code-specification.html 我向往这样一个php世界,里面没有代码规范之争.你我都一样,都 ...
- 2016 正确 sublime安装PHPcs PHPcodesniffer代码规范提示插件,修正网上部分不详细描述
对你有助请点赞,请顶,不好请踩------送人玫瑰,手留余香!-------------------14:37 2016/3/212016 正确 sublime安装PHPcs PHPcodesniff ...
- C#与Java对比学习:类型判断、类与接口继承、代码规范与编码习惯、常量定义
类型判断符号: C#:object a; if(a is int) { } 用 is 符号判断 Java:object a; if(a instanceof Integer) { } 用 inst ...
- 作业三: 代码规范、代码复审、PSP
分) 对于是否需要有代码规范,请考虑下列论点并反驳/支持: 这些规范都是官僚制度下产生的浪费大家的编程时间.影响人们开发效率, 浪费时间的东西. 我是个艺术家,手艺人,我有自己的规范和原则. 规范不能 ...
- 转!!Java代码规范、格式化和checkstyle检查配置文档
为便于规范各位开发人员代码.提高代码质量,研发中心需要启动代码评审机制.为了加快代码评审的速度,减少不必要的时间,可以加入一些代码评审的静态检查工具,另外需要为研发中心配置统一的编码模板和代码格式化模 ...
- C#代码规范
C#代码规范 一.文件命名 1 文件名 文件名统一使用帕斯卡命名法,以C#类名命名,拓展名小写. 示例: GameManager.cs 2 文件注释 每个文件头须包含注释说明,文件头位置指的是文件最 ...
- 【转】Java代码规范
[转]Java代码规范 http://blog.csdn.net/huaishu/article/details/26725539
随机推荐
- java中的线程是如何工作的。
来自对此文章的编辑. https://mp.weixin.qq.com/s?biz=MzA5NDg3MjAwMQ==&mid=2457103451&idx=1&sn=ba302 ...
- SpringMVC 解析(二)DispatcherServlet
在我的关于Tomcat容器介绍的文章中,介绍了Tomcat容器的工作原理,我们知道Tomcat容器在收到请求之后,会把请求处理为Request/Response对象,交给Servlet实例处理.对于S ...
- 不使用pvc的方式在K8S中部署apisix-gateway
不使用pvc的方式在K8S中部署apisix-gateway 简介 我的apisix使用etcd作为数据存储服务器,官方的使用pvc方式或者docker-compose的方式,对于新手不太友好,本篇是 ...
- 部分文件的MIMEType
类型 文件拓展名 MIMEType 图片 png image/png bmp\dib image/bmp jpe\jpeg\jpg image/jpeg gif image/gif 多媒体 mp3 a ...
- php include,require,include_once,require_once 的区别
include(),require(),include_once(),require_once()作用都是包含并运行指定文件,但是使用场景又有很大区别. 1.include()和require()的区 ...
- 区段统计 mysql 语句 case when then end as
EXPLAIN SELECT COUNT(*),CASEWHEN device_width > 729 THEN '>729'WHEN device_width BETWEEN '720' ...
- GFS 分布式文件系统
GFS 分布式文件系统 1.GlusterFS概述 : GlusterFS简介 a) GlusterFS是一-个开源的分布式文件系统. 由存储服务器.客户端以及NFS/Samba存储网关(可选,根据 ...
- k8s之PV、PVC
目录 一.PVC和PV 1.1 PV概念 1.2 PVC概念 1.3 PV与PVC之间的关系 1.4 两种PV的提供方式 二.基于nfs创建静态PV资源和PVC资源 2.1 配置nfs存储(192.1 ...
- 四路4 GSPS@ 12 bit,四路12 GSPS@16 位4T4R 射频芯片AD9988
一.产品概述 AD9988 是一款高度集成的套件,是北京太速最新研发的,具有四个 16 位.12 GSPS 最大采样率.RF 数模转换器 (DAC) 内核,以及四个 12 位.4 GSPS 速率.RF ...
- Solution -「Gym 102979E」Expected Distance
\(\mathcal{Description}\) Link. 用给定的 \(\{a_{n-1}\},\{c_n\}\) 生成一棵含有 \(n\) 个点的树,其中 \(u\) 连向 \([1, ...