Go 箴言
- 不要通过共享内存进行通信,通过通信共享内存
- 并发不是并行
- 管道用于协调;互斥量(锁)用于同步
- 接口越大,抽象就越弱
- 利用好零值
- 空接口 interface{} 没有任何类型约束
- Gofmt 的风格不是人们最喜欢的,但 gofmt 是每个人的最爱
- 允许一点点重复比引入一点点依赖更好
- 系统调用必须始终使用构建标记进行保护
- 必须始终使用构建标记保护 Cgo
- Cgo 不是 Go
- 使用标准库的 unsafe 包,不能保证能如期运行
- 清晰比聪明更好
- 反射永远不清晰
- 错误是值
- 不要只检查错误,还要优雅地处理它们
- 设计架构,命名组件,(文档)记录细节
- 文档是供用户使用的
- 不要(在生产环境)使用 panic()
- 每个 package 实现单一的目的
- 显式处理错误
- 尽早返回,而不是使用深嵌套
- 让调用者处理并发(带来的问题)
- 在启动一个 goroutine 时,需要知道何时它会停止
- 避免 package 级别的状态
- 简单很重要
- 编写测试以锁定 package API 的行为
- 如果你觉得慢,先编写 benchmark 来证明
- 适度是一种美德
- 可维护性
尝试减少代码复杂度 。这将帮助所有人使代码易于阅读 。
多个 if 语句可以折叠成 switch
// NOT BADif foo() {// ...} else if bar == baz {// ...} else {// ...}// BETTERswitch {case foo():// ...case bar == baz:// ...default:// ...}用chan struct{}来传递信号,chan bool表达的不够清楚当你在结构中看到 chan bool 的定义时,有时不容易理解如何使用该值,例如:type Service struct {deleteCh chan bool // what does this bool mean? }但是我们可以将其改为明确的 chan struct {} 来使其更清楚:我们不在乎值(它始终是 struct {}),我们关心可能发生的事件,例如:type Service struct {deleteCh chan struct{} // ok, if event than delete something.}30 * time.Second比time.Duration(30) * time.Second更好你不需要将无类型的常量包装成类型,编译器会找出来 。另外最好将常量移到第一位:
// BADdelay := time.Second * 60 * 24 * 60// VERY BADdelay := 60 * time.Second * 60 * 24// GOODdelay := 24 * 60 * 60 * time.Second用time.Duration代替int64+ 变量名// BADvar delayMillis int64 = 15000// GOODvar delay time.Duration = 15 * time.Second按类型分组const声明,按逻辑和/或类型分组var// BADconst (foo = 1bar = 2message = "warn message")// MOSTLY BADconst foo = 1const bar = 2const message = "warn message"// GOODconst (foo = 1bar = 2)const message = "warn message"这个模式也适用于 var 。- 每个阻塞或者 IO 函数操作应该是可取消的或者至少是可超时的
- 为整型常量值实现 Stringer 接口https://godoc.org/golang.org/x/tools/cmd/stringer
- 检查 defer 中的错误
defer func() {err := ocp.Close()if err != nil {rerr = err}}()- 不要在 checkErr 函数中使用 panic() 或 os.Exit()
- 仅仅在很特殊情况下才使用 panic, 你必须要去处理 error
- 不要给枚举使用别名,因为这打破了类型安全https://play.golang.org/p/MGbeDwtXN3
package maintype Status = inttype Format = int // remove `=` to have type safetyconst A Status = 1const B Format = 1func main() {println(A == B)}- 如果你想省略返回参数,你最好表示出来
- _ = f() 比 f() 更好
- 我们用 a := []T{} 来简单初始化 slice
- 用 range 循环来进行数组或 slice 的迭代
- for _, c := range a[3:7] {...} 比 for i := 3; i < 7; i++ {...} 更好
- 多行字符串用反引号(`)
- 用 _ 来跳过不用的参数
推荐阅读
- go并发编程
- 用电饭煲蒸米饭放点红小豆怎么做 用电饭煲蒸米饭放点红小豆如何做
- 明朝末年小冰河,明末的小冰河时期-
- 显示器|618秒杀仍在继续!攀升4款显示器促销:144Hz直男小钢炮到手价699元
- 世界上有狐妖小红娘吗-,狐妖小红娘那件事到底是什么-
- 取名要看五行缺什么吗,小孩取名五行八字缺什么怎么查-
- 小米|2022年安卓之光!卢伟冰换上小米12 Ultra
- 小米|小米12 Ultra把高通骁龙8+彻底驯服了 雷军:不调好绝不发布
- 雷军|骁龙8+被低估了 雷军上手后有感而发:实际体验绝对不是“小升级”
- 骁龙888|疑似小米平板6新品已备案:SoC大升级 或用上骁龙888
