引言
Go
语言是从既有的语言中借鉴了许多理念,但其与众不同的特性, 使得使用 Go
编程在本质上就不同于其它语言。将现有的 C++
或 Java
程序直译为 Go
程序并不能令人满意 —— 毕竟 Java
程序是用 Java
编写的,而不是 Go
。 另一方面,若从 Go
的角度去分析问题,你就能编写出同样可行但大不相同的程序。 换句话说,要想将 Go
程序写得好,就必须理解其特性和风格。了解命名、格式化、 程序结构等既定规则也同样重要,这样你编写的程序才能更容易被其他程序员所理解。
本文主要摘录了日常开发过程中,会遇到的一些需要注意的事项,若想阅读原文,请参考文末链接。
命名与格式
对于格式化而言,Go
默认已经有了 gofmt
工具,我们可以使用其对编写的代码按照标准风格缩进、对齐等。同时,在编码的时候,一些命名规范也需要注意,避免出现一些隐藏的bug。
在 vscode
中可以使用快捷键:alt+shift+F
(shift+option+F
)直接使用(CoLand
则为ctrl+alt+L
)。还有 goimport
和 go vet
工具对应自动删除和引入包,以及静态分析代码是否符合标准。
// 获取方式
go get golang.org/x/tools/cmd/goimports
go get golang.org/x/tools/cmd/vet
-
包及格式
包应当以小写的单个单词来命名,且不应使用下划线或驼峰记法
还有一点,就是自建包的函数命名也需遵循简洁明了的准则,如
bufio.Reader
而非bufio.BufReader
。once.Do
表述足够清晰, 使用once.DoOrWaitUntilDone(setup)
就有点画蛇添足包的import规范:应当按:标准库,项目包,第三方包的顺序组织在import中,中间采用空行隔开:
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”
-
变量命名
约定采用驼峰法命名参数,如
MixedCaps
或mixedCaps
而不是下划线,首字母根据访问控制原则大写或者小写多个变量申明最好放在一起,如:
var ( Found bool count int )
在函数外部申明必须使用var,不要采用
:=
,容易踩到变量的作用域的坑-
注意特有名词的使用:
- 如果变量为私有,且特有名词为首个单词,则使用小写,如
apiClient
- 其它情况都应当使用该名词原有的写法,如
APIClient
- 若变量类型为 bool 类型,则名称应以
Has
,Is
,Can
或Allow
开头
- 如果变量为私有,且特有名词为首个单词,则使用小写,如
-
常量均需使用全部大写字母组成,并使用下划线分词
const APP_VER = "1.0"
-
文件命名
- 尽量采取有意义的文件名,简短,有意义,应该为**小写**单词,使用**下划线**分隔各个单词。
-
结构体命名
- 采用驼峰命名法,首字母根据访问控制大写或者小写
-
缩进与行长
- 使用制表符(tab)缩进,
gofmt
默认也使用它,在你认为确实有必要时再使用空格 - Go 对行的长度没有限制,但是建议不要超过80个字符,超过的请使用换行展示,尽量保持格式优雅
- 使用制表符(tab)缩进,
代码注释
Go提供C风格的 /* */
块注释和 C++
风格的 //
行注释。行注释是常态;块注释主要显示为包注释,但在表达式中很有用或禁用大量代码。
-
包注释
-
每个包都应该有一个包注释,包注释应该包含下面基本信息:
包的基本简介(包名,简介) 创建者,格式: 创建人: rtx 名 创建时间,格式:创建时间: yyyyMMdd 如: // util 包, 该包包含了项目共用的一些常量,封装了项目中一些共用函数。 // 创建人: hope // 创建时间: 20221116
-
-
结构(接口)及函数(方法)注释
-
结构体或者函数最好都有对应的注释说明,说明的格式其实和其他语言是大致一样的,这里建议是包含以下几个部分:简要说明、参数列表、返回值。此项不做强制要求,但至少需要有一行简要说明
// NewtAttrModel , 属性数据层操作类的工厂方法 // 参数: // ctx : 上下文信息 // 返回值: // 属性操作类指针 func NewAttrModel(ctx *common.Context) *AttrModel { }
-
-
代码逻辑注释及风格
对于一些关键位置的代码逻辑,或者局部较为复杂的逻辑,需要有相应的逻辑说明
-
统一使用中文注释,对于中英文字符之间严格使用空格分隔,同时注释长度也不宜过长
// 从 Redis 中批量读取属性,对于没有读取到的 id , 记录到一个数组里面,准备从 DB 中读取
错误
错误处理的原则就是不能丢弃任何有返回err的调用,不要使用
_
丢弃,必须全部处理。接收到错误,要么返回err
,或者使用log
记录下来尽早
return
,而不是一味地使用else
,一旦有错误发生,马上返回尽量不要使用
panic
,除非你知道你在做什么,错误描述如果是英文必须为小写,不需要标点结尾
-
采用独立的错误流进行处理
// 错误写法 if err != nil { // error handling } else { // normal code } // 正确写法 if err != nil { // error handling return // or continue, etc. }
其他
打开文件或者其他资源时,要注意记得释放,最常用的就是使用
defer
Go 还有许多特性,切片、映射、打印、追加,这里不一一赘述,有兴趣可以自行学习一下,灵活使用这些特性可以极大的提高编码效率以及代码可读性
参考资料:Effective Go