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
随机推荐
- 阿里智能运维实践|阿里巴巴DevOps实践指南
编者按:本文源自阿里云云效团队出品的<阿里巴巴DevOps实践指南>,扫描上方二维码或前往:https://developer.aliyun.com/topic/devops,下载完整版电 ...
- 资本主义反抗指南精要(v0.1)
(1)充分预估工作时间,比如一小时的开发任务,你可以加上技术调研,API/数据库设计,单元测试,联调,集成测试等等,拖到一天,同理一天的任务可以拖到一星期. (2)简历上尽一切手段来美化,最好能包装成 ...
- 记录常见的问题:encodeURICompnent 解码过程中出现空格 以及 第三方app中使用schema 唤起app
window.location.href 跳转的时候使用了encodeURIComponent编码了部分参数,但是在第三方app中出现了编码过后的参数换行和空格的情况(部分第三方应用或者java程序) ...
- java实现以docx格式导出
直接上代码:Map<String, Object> dataMap = afterLoanReportService.exportReport(startDate, endDate);// ...
- Linux Shell脚本攻略复习
1. 打开终端后的提示符中,$表示普通用户,#表示管理员用户root,root是linux系统中权限最高的用户. 2. shell脚本通常是一个#!起始的文本文件,其中#!位于解释器路径之前. 例如: ...
- array_multisort array_merge 排序
前段时间遇到一个排序问题,大致是这样的:$demo = array( 0 => array( 'name' ...
- Java产生指定范围内的随机日期
要想产生指定范围内的随机日期,首先我们要指定一个范围,那么我们可以通过SImpleDateFormat格式化日期,然后再通过parse()方法设置日期,返回一个Date类型的日期对象,再转化为时间戳( ...
- Hadoop完全分布式的配置
选取机器sam01作为主节点,并进行分布式文件的配置 1.进入Hadoop配置文件路径/usr/local/hadoop/etc/hadoop(这里我把Hadoop安装在/usr/local目录下) ...
- 降维处理PCA
要理解什么是降维,书上给出了一个很好但是有点抽象的例子. 说,看电视的时候屏幕上有成百上千万的像素点,那么其实每个画面都是一个上千万维度的数据:但是我们在观看的时候大脑自动把电视里面的场景放在我们所能 ...
- PHP爱考的那些笔试题
PHP爱考的那些笔试题 来自<PHP程序员面试笔试宝典>,涵盖了近三年了各大型企业常考的PHP面试题,针对面试题提取出来各种面试知识也涵盖在了本书. 一.单例模式是在应用程序中最多只能拥有 ...