Go代码规范(Code Review)

总结几个开发过程中经常会犯的代码规范错误

参考链接:https://learnku.com/go/wikis/48375

注释语句

// 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 。 避免使用像 utilcommonmiscapitypesinterfaces 这样无意义的包名。

不要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 indicesreaders 的名称用一个字母(i , r)指代就可以。

当然,对于一些逻辑比较复杂的逻辑,或者非常规事物,或者全局变量则需使用更具描述性的名字。

Go代码规范梳理的更多相关文章

  1. Scrum立会报告+燃尽图(十一月十五日总第二十三次):代码规范与技术交流

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2384 项目地址:https://git.coding.net/zhang ...

  2. iOS代码规范(OC和Swift)

    下面说下iOS的代码规范问题,如果大家觉得还不错,可以直接用到项目中,有不同意见 可以在下面讨论下. 相信很多人工作中最烦的就是代码不规范,命名不规范,曾经见过一个VC里有3个按钮被命名为button ...

  3. 谈谈PHP代码规范

    [转] http://www.syyong.com/php/Talk-about-PHP-code-specification.html 我向往这样一个php世界,里面没有代码规范之争.你我都一样,都 ...

  4. 2016 正确 sublime安装PHPcs PHPcodesniffer代码规范提示插件,修正网上部分不详细描述

    对你有助请点赞,请顶,不好请踩------送人玫瑰,手留余香!-------------------14:37 2016/3/212016 正确 sublime安装PHPcs PHPcodesniff ...

  5. C#与Java对比学习:类型判断、类与接口继承、代码规范与编码习惯、常量定义

    类型判断符号: C#:object a;  if(a is int) { }  用 is 符号判断 Java:object a; if(a instanceof Integer) { } 用 inst ...

  6. 作业三: 代码规范、代码复审、PSP

    分) 对于是否需要有代码规范,请考虑下列论点并反驳/支持: 这些规范都是官僚制度下产生的浪费大家的编程时间.影响人们开发效率, 浪费时间的东西. 我是个艺术家,手艺人,我有自己的规范和原则. 规范不能 ...

  7. 转!!Java代码规范、格式化和checkstyle检查配置文档

    为便于规范各位开发人员代码.提高代码质量,研发中心需要启动代码评审机制.为了加快代码评审的速度,减少不必要的时间,可以加入一些代码评审的静态检查工具,另外需要为研发中心配置统一的编码模板和代码格式化模 ...

  8. C#代码规范

    C#代码规范  一.文件命名 1 文件名 文件名统一使用帕斯卡命名法,以C#类名命名,拓展名小写. 示例: GameManager.cs 2 文件注释 每个文件头须包含注释说明,文件头位置指的是文件最 ...

  9. 【转】Java代码规范

    [转]Java代码规范 http://blog.csdn.net/huaishu/article/details/26725539

随机推荐

  1. python02day

    回顾 1.编译型和解释型 编译型:一次性编译成二进制,再执行 执行效率高,但不能跨平台,开发效率低 代表语言:C 解释型:逐行解释成二进制,再执行 可以跨平台,开发效率高,但执行效率低 代表语言:py ...

  2. Jvm内存回收

    一.什么内存会被回收 可达性分析算法 通过一系列的GC ROOT的对象作为超始点,从这些节点开始向下搜索,搜索所走的路径称为"引用链",当一个对象到GC ROOT之间没有任何引用链 ...

  3. ApacheCN Linux 译文集(二) 20211206 更新

    CentOS7 Linux 服务器秘籍 零.前言 一.安装 CentOS 二.配置系统 三.管理系统 四.用 YUM 管理包 五.管理文件系统 六.提供安全性 七.构建网络 八.使用文件传输协议 九. ...

  4. Java 高效编程(Effective Java)中文第三版(补档)

    来源:sjsdfg/effective-java-3rd-chinese <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过, ...

  5. UIView属性的讲解

    1.父控件和子控件的理解在storyboard中只有UIView是可以在里面拖入子控件的,其他控件不可以(必须通过代码添加)拖入一个UIView控件,在里面添加一些子控件(UIView控件是控制器的V ...

  6. Ajax向服务器发起请求

    Ajax向服务器发起请求的三个步骤: 1:创建Ajax 2:打开Ajax,打开Ajax请求 3:向服务器发起请求:需要知道地址和是get请求还是post方法 向服务器发起请求的两个方法:open 和 ...

  7. 使用python实现冒泡排序和快速排序

    1 def bubble(arr): 2 """冒泡排序""" 3 loop = len(arr) - 1 4 if loop > 0 ...

  8. 直播媒体流red5

    第一步下载 安装setup-Red5-1.0.1-java6.exe 安装教程网上有很多 显示如下页面说明安装成功 第二步 下载oflaDemo的 解压放在 第三步  打开 然后 ok了 注意:下面的 ...

  9. shell脚本命令(sotr/unip/tr/cut/eval)与正则表达式

    shell脚本命令(sotr/unip/tr/cut/eval)与正则表达式 1.sort命令 概述: Linux sort命令用于将文本文件内容加以排序. sort命令可针对文本文件的内容,以行为单 ...

  10. web虚拟主机、日志分割以及日志分析

    目录 一.构建虚拟web主机 1.1 概述 1.2 支持的虚拟主机类型 1.3 部署虚拟主机步骤 1.3.1 基于域名的虚拟主机 (1)为虚拟主机提供域名解析 (2)为虚拟主机准备网页文档 (3)添加 ...