官方文档effective go是学习go语言的必读文档。此篇文章为官方文档的中文翻译版并做了精简总结,方便学习回顾。
目录
1. 介绍
2. 格式化
3. 注释
4. 命名
5. 分号
6. 控制结构
7. 函数
8. 数据
9. 初始化
10. 方法
11. 接口和其它类型
12. 空白标识符
13. 内嵌
14. 并发
15. 错误处理
1. 介绍
本文档提供了编写清晰、惯用的GO代码的技巧。
2. 格式化
gofmt自动生成统一风格代码格式,程序员无需关心代码格式问题。
3. 注释
Go提供C风格的块注释/* */
和C++风格的行注释//
。一般使用行注释,包注释使用块注释。
4. 命名
首字母大写的命名包外可见。
包名
包名应该简洁明了,便于记忆。建议是一个小写单词,不包含下划线和混合大小写。
import "src/encoding/base64"
后,导入包用base64
代替。这使得包中导出名字避免冗余,bufio.Reader
和bufio.BufReader
相比,更简洁明了。
Getters
小写命名做为包内成员变量,大写命名做为公开成员读方法,公开成员写方法。例如,owner
为包内成员变量,Owner()
为公开方法返回owner
,SetOwner()
为公开方法修改owner
变量。
接口命名
单方法接口采用方法名加er
后缀方式命名,例如Reader
,Wrtier
。除非用途和签名完全一致,不要采用Read
,Write
,String
等系统保留方法名。转换字符串的方法名为String
而非ToString
。
多词命名
采用MixedCaps或mixedCaps风格,而非下划线。
5. 分号
大多数情况下不需要输入分号,go语法分析器会自动插入。for语句或多条语句在一行时,需要输入分号分割语句。自动插入的一个副作用是左花括号不能在一行开头。
6. 控制结构
If
if可以接受一个初始语句
if err := file.Chmod(0664); err != nil {
log.Print(err)
return err
}
重声明和重赋值
f, err := os.Open(name)
这条语句声明并赋值两个变量f
和err
。符合下面条件时:=
可对已存在变量v
重赋值。
- 同一作用域中
v
已存在。(否则在不同作用域中声明新变量v
) - 右边值可以正确赋给
v
- 至少产生一个新声明变量
例如,d, err := f.Stat()
go语言中,函数参数和返回值同函数体具有相同的作用域。
For
// Like a C for
for init; condition; post { }
// Like a C while
for condition { }
// Like a C for(;;)
for { }
针对集合对象,使用range
for key, value := range oldMap {
newMap[key] = value
}
for key := range m {
if key.expired() {
delete(m, key)
}
}
sum := 0
for _, value := range array {
sum += value
}
go不支持++
,--
运算,但支持多赋值
// Reverse a
for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 {
a[i], a[j] = a[j], a[i]
}
Switch
go的switch表达式可以不为常量甚至不为数字,依次比较每个case直到匹配。表达式为空意味匹配true
。
func unhex(c byte) byte {
switch {
case '0' <= c && c <= '9':
return c - '0'
case 'a' <= c && c <= 'f':
return c - 'a' + 10
case 'A' <= c && c <= 'F':
return c - 'A' + 10
}
return 0
}
匹配成功后就会返回,case子句支持逗号分隔。
func shouldEscape(c byte) bool {
switch c {
case ' ', '?', '&', '=', '#', '+', '%':
return true
}
return false
}
break
在swtich中并不常见,但也可以和label配合,直接跳到外层。
Loop:
for n := 0; n < len(src); n += size {
switch {
case src[n] < sizeOne:
if validateOnly {
break
}
size = 1
update(src[n])
case src[n] < sizeTwo:
if n+1 >= len(src) {
err = errShortInput
break Loop
}
if validateOnly {
break